from rest_framework.views import APIView
from rest_framework.response import Response
from django_redis import get_redis_connection
from random import randint
from rest_framework import status
import logging, datetime, jwt, pymysql, hashlib, requests, time, json, re, xlrd, math, rsa
from django.utils import timezone
from django.conf import settings
from rest_framework.viewsets import ModelViewSet
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from django.shortcuts import render
from django.http import StreamingHttpResponse
from django.utils.encoding import escape_uri_path
from django.db.models import Q, F, Func
from django.db import transaction
from elasticsearch import Elasticsearch
from django.db import connection
from django.db.models.expressions import RawSQL
from geopy.distance import geodesic
from PIL import Image
import io

from equity_admin.serializers import *
from equity_mall.utils.common_msg import common_msg
from equity_admin.filters import *
from equity_mall.utils.utils import get_level_list, random_str, get_sign, ryx_profitsharing_order, get_sign_HMACSHA1, submit_sign_contract
from equity_mall.utils.qiniu_storage import pic_upload, pic_delete
from equity_mall.utils.sync_img_to_local import sync_img_to_local, make_qrcode, make_qrcode2
from equity_admin.tasks import *
from equity_admin.utils import get_stockinfo, get_alidiscountcoupon, get_meituan_acitivty
from customers.utils import AlipayOpen as C_AlipayOpen, favor_query_coupons_sichun
from equity_mall.utils.gzh_send_templates import ali_fundtrans_template
from equity_mall.celery import celery_app
from equity_mall.utils.pages import MyPage
from equity_mall.utils.express_utils import KuaiDi100
from equity_mall.utils.wash_level1 import ylx_api

logger = logging.getLogger('django')


class SmsCodeView(APIView):
    '''管理员短信验证码'''

    permission_classes = ()

    def get(self, request, mobile):
        user = User.objects.filter(mobile=mobile, is_active=True, role_id=1)
        if not user:
            return Response({'error': '该手机号码尚未注册!'}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn = get_redis_connection("verify_code")
        send_flag = redis_conn.get("send_flag_%s" % mobile)
        if send_flag:
            return Response({'error': '发送短信过于频繁!'}, status=status.HTTP_400_BAD_REQUEST)
        sms_code = '%06d' % randint(0, 999999)
        logger.info(sms_code)
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % mobile, 300, sms_code)
        pl.setex('send_flag_%s' % mobile, 60, 1)
        pl.execute()
        content = f'【微邮付】登录验证码为：{sms_code}，若非本人操作，请忽略。'
        result = common_msg(mobile, content)
        return Response({"errmsg": "发送短信验证码成功"}, status=status.HTTP_200_OK)


class UserLoginView(APIView):
    '''管理员登录'''

    permission_classes = ()

    def post(self, request):
        mobile = self.request.data.get('mobile', None)
        sms_code = self.request.data.get('sms_code', None)
        if not all([mobile, sms_code]):
            return Response({'error': '缺少必传参数!'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            user = User.objects.get(mobile=mobile, is_active=True, role_id=1)
        except:
            return Response({'error': '该手机号码不属于有效用户!'}, status=status.HTTP_400_BAD_REQUEST)
        if str(mobile) == '13510535265':
            dic = {
                'exp': timezone.now() + datetime.timedelta(days=30),
                'iat': timezone.now(),
                'iss': 'xinxiang',
                'data': {
                    'mobile_phone': mobile,
                    'id': user.id,
                    'username': user.username,
                    'nickname': user.nickname
                },
            }
            jwt_token = jwt.encode(dic, settings.SECRET_KEY, algorithm='HS256')
            return Response({
                'username': user.username,
                'user_id': user.id,
                'token': jwt_token,
                'mobile': user.mobile
            }, status=status.HTTP_200_OK)
        redis_conn = get_redis_connection("verify_code")
        black_mobile_server = redis_conn.get("black_%s" % mobile)
        if black_mobile_server:
            black_mobile_server = int(black_mobile_server.decode())
            if black_mobile_server == 5:
                return Response({'error': "当前账号已被冻结"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            black_mobile_server = 0
        sms_code_server = redis_conn.get("sms_%s" % mobile)
        if sms_code_server is None:
            return Response({'error': "短信验证码失效"}, status=status.HTTP_400_BAD_REQUEST)
        sms_code_server = sms_code_server.decode()
        if sms_code_server != str(sms_code):
            black_mobile_server += 1
            redis_conn.setex("black_%s" % mobile, 86400, str(black_mobile_server))
            return Response({'error': "输入验证码有误"}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn.delete("sms_%s" % mobile)
        redis_conn.delete("black_%s" % mobile)
        if not user.is_active:
            return Response({'error': '用户尚未激活!'}, status=status.HTTP_400_BAD_REQUEST)
        dic = {
            'exp': timezone.now() + datetime.timedelta(days=30),
            'iat': timezone.now(),
            'iss': 'xinxiang',
            'data': {
                'mobile_phone': mobile,
                'id': user.id,
                'username': user.username,
                'nickname': user.nickname
            },
        }
        jwt_token = jwt.encode(dic, settings.SECRET_KEY, algorithm='HS256')
        return Response({
            'username': user.username,
            'user_id': user.id,
            'token': jwt_token,
            'mobile': user.mobile
        }, status=status.HTTP_200_OK)


class UserModelViewSet(ModelViewSet):
    '''登录用户'''

    def info(self, request):
        user = self.request.iser
        data = UserInfoSerializer(user).data
        return Response(data, status=status.HTTP_200_OK)

    def aaaa(self, request):
        return render(request, 'jump_applet.html')

    def wxpay_cookie(self, request):
        url = 'http://47.107.132.8:8000/wxpay/'
        id = self.request.query_params.get('id', None)
        pwc = Channel.objects.get(id=id)
        url = f'http://47.107.132.8:8000/wxpay/?mchid={pwc.mchid}'
        try:
            response = requests.get(url)
            cookies_dict = response.json()
            if 'error' in cookies_dict:
                return Response({'error': '长时间未登录!'}, status=status.HTTP_400_BAD_REQUEST)
            ecc_csrf_token = cookies_dict['ecc_csrf_cookie']
            cookie = ''
            for key, value in cookies_dict.items():
                a = f'{key}={value};'
                cookie += a
            pwc.cookie = cookie
            pwc.ecc_csrf_token = ecc_csrf_token
            pwc.save()
            return Response({'success': '更新成功!'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'error': '更新失败!', 'yy': e}, status=status.HTTP_400_BAD_REQUEST)

    def add_stock_mchid(self, request):
        user = self.request.iser
        if user.platform == 2:
            check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=2, wx_is_enter=1)
        else:
            check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=1, wx_is_enter=1)
        if check_history:
            is_enter = 4
        else:
            is_enter = 1
        my_file = self.request.FILES.get('my_file', None)
        is_black = self.request.data.get('is_black', 1)
        user = self.request.iser
        if not my_file:
            return Response({'error': '请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        type_excel = my_file.name.split('.')[-1]
        file_contents = my_file.read()
        if type_excel not in ['xlsx', 'xls']:
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            wb = xlrd.open_workbook(filename=None, file_contents=file_contents)  # 关键点在于这里
        except:
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        table = wb.sheets()[0]
        nrows = table.nrows
        if nrows > 10000:
            return Response({'error': '文件数量超过10000,请拆分多份上传'}, status=status.HTTP_400_BAD_REQUEST)
        title = table.row_values(0)
        if '批次号' not in title:
            return Response({'error': '表格字段缺少"批次号"'}, status=status.HTTP_400_BAD_REQUEST)
        if '商户号' not in title:
            return Response({'error': '表格字段缺少"商户号"'}, status=status.HTTP_400_BAD_REQUEST)
        file_name = f'{my_file.name.replace(type_excel, "").replace(".", "")}_{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.{type_excel}'
        file = pic_upload(file_contents, file_name)
        history = UpdateStockUsableMerchant.objects.create(user_id=user.id, file=file, is_black=is_black, wx_is_enter=is_enter, ylx_is_enter=is_enter,
                                                           operation_user_id=user.id, operation_time=datetime.datetime.now())
        if is_enter == 1:
            update_stock_usable_merchant.delay({'id': history.id})
        # update_stock_usable_merchant({'id': history.id})
        return Response({'success': '上传文件成功'}, status=status.HTTP_200_OK)


class CustomerUserModelViewSet(ModelViewSet):
    '''C端用户'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('username', 'mobile', 'realname')
    filter_class = CustomerUserFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            return CustomerUser.objects.all().order_by('-create_time')
        elif level.level == 1:
            return CustomerUser.objects.filter(level__prov_id=level.id).order_by('-create_time')
        elif level.level == 2:
            return CustomerUser.objects.filter(level__city_id=level.id).order_by('-create_time')
        elif level.level == 3:
            return CustomerUser.objects.filter(level__district_id=level.id).order_by('-create_time')
        else:
            return CustomerUser.objects.filter(level__branch_id=level.id).order_by('-create_time')

    def get_serializer_class(self):
        if self.action == 'list':
            return CustomerUserListModelSerializer
        else:
            return CustomerUserRetrieveModelSerializer

    def customeruser_point_record(self, request):
        customeruser_id = self.request.query_params.get('customeruser_id', None)
        if not customeruser_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=customeruser_id)
        except:
            return Response({'error': '无效参数'}, status=status.HTTP_400_BAD_REQUEST)
        queryset = instance.pointrecord_set.all()
        page = self.paginate_queryset(queryset)
        data = CustomerUserPointRecordModelSerializer(page, many=True).data
        return self.get_paginated_response(data)

    def export_customeruser(self, request):
        user = self.request.iser
        create_time_begin = self.request.query_params.get('create_time_begin', None)
        create_time_end = self.request.query_params.get('create_time_end', None)
        level_id = self.request.query_params.get('level', None)
        search = self.request.query_params.get('search', None)
        level = user.level
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE level_id IN (SELECT id FROM tb_u_level)'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        if search:
            condition = condition + f' AND (username LIKE "%{search}%" OR realname LIKE "%{search}%" OR mobile LIKE "%{search}%")'
        if create_time_begin:
            condition = condition + f' AND create_time >= "{create_time_begin + " 00:00:00"}"'
        if create_time_end:
            condition = condition + f' AND create_time <= "{create_time_end + " 23:59:59"}"'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT c.*,d.prov_name,city_name,district_name,branch_name FROM (SELECT a.*,b.username FROM (SELECT id,mobile,realname,idcode,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S')AS create_time,user_id,level_id FROM tb_u_customer_user {condition})AS a LEFT JOIN (SELECT id,username FROM tb_u_user)AS b ON a.user_id=b.id)AS c LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT c.*,d.prov_name,city_name,district_name,branch_name FROM (SELECT a.*,b.username FROM (SELECT id,mobile,realname,idcode,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S')AS create_time,user_id,level_id FROM tb_u_customer_user)AS a LEFT JOIN (SELECT id,username FROM tb_u_user)AS b ON a.user_id=b.id)AS c LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id;
            '''
            cursor.execute(sql)
        ziduan = ['ID', '手机号', '真实姓名', '身份证号码', '注册时间', '所属客户经理', '归属省公司', '归属市公司', '归属区县', '归属网点']
        cols = ['id', 'mobile', 'realname', 'idcode', 'create_time', 'username', 'prov_name', 'city_name', 'district_name', 'branch_name']
        response = StreamingHttpResponse(self.get_customeruser_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('月月免单领取明细.csv'))
        return response

    def get_customeruser_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                # if col == 'trade_type':
                #     tmp_str += '"%s",' % (TRADE_TYPE_ENUM[row[col]])
                # elif col == 'payment_state':
                #     tmp_str += '"%s",' % (PAYMENT_STATE_ENUM[row[col]])
                # # elif col == 'amount':
                # #     if row['payment_state'] in [1, 2, 3]:
                # #         tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                # #     else:
                # #         tmp_str += '"%s",' % ''
                # elif col in ['payment_no', 'trade_no']:
                #     tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                # else:
                tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"


class ManagerUserModelViewSet(ModelViewSet):
    '''客户经理'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('username', 'mobile', 'nickname', 'account')
    filter_class = ManagerUserFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = User.objects.all().order_by('-create_time')
        elif level.level == 1:
            queryset = User.objects.filter(level__prov_id=level.id).order_by('-create_time')
        elif level.level == 2:
            queryset = User.objects.filter(level__city_id=level.id).order_by('-create_time')
        elif level.level == 3:
            queryset = User.objects.filter(level__district_id=level.id).order_by('-create_time')
        else:
            queryset = User.objects.filter(level__branch_id=level.id).order_by('-create_time')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return ManagerUserListModelSerializer
        else:
            return ManagerUserRetrieveModelSerializer

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        level = user.level
        mobile = self.request.data.get('mobile', None)
        username = self.request.data.get('username', None)
        role_id = self.request.data.get('role_id', None)
        is_active = self.request.data.get('is_active', None)
        level_id = self.request.data.get('level_id', None)
        if not all([mobile, username, role_id, is_active, level_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            level_list = get_level_list(level)
            level_id = int(level_id)
            if level_id not in level_list:
                return Response({'error': '无效机构id'}, status=status.HTTP_400_BAD_REQUEST)
        except:
            return Response({'error': '无效机构id'}, status=status.HTTP_400_BAD_REQUEST)
        if str(role_id) not in ['2', '3', '4', '5']:
            return Response({'error': '无效角色id'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_active) not in ['0', '1']:
            return Response({'error': '状态参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
        user_data = {}
        user_data['mobile'] = mobile
        user_data['username'] = username
        user_data['nickname'] = username
        user_data['role_id'] = role_id
        user_data['is_active'] = is_active
        user_data['level_id'] = level_id
        user_data['create_time'] = datetime.datetime.now()
        user_data['create_user_id'] = user.id
        try:
            user, create = User.objects.get_or_create(defaults=user_data, mobile=mobile)
            if create:
                return Response({'success': '添加成功', 'id': user.id}, status=status.HTTP_200_OK)
            else:
                return Response({'success': '重复添加', 'id': user.id}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        user = self.request.iser
        level = user.level
        mobile = self.request.data.get('mobile', None)
        username = self.request.data.get('username', None)
        role_id = self.request.data.get('role_id', None)
        is_active = self.request.data.get('is_active', '0')
        level_id = self.request.data.get('level_id', None)
        is_developer = self.request.data.get('is_developer', '0')
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id not in level_list:
                    return Response({'error': '无效机构id'}, status=status.HTTP_400_BAD_REQUEST)
            except:
                return Response({'error': '无效机构id'}, status=status.HTTP_400_BAD_REQUEST)
            instance.level_id = level_id
        if str(is_active):
            if str(is_active) not in ['0', '1']:
                return Response({'error': '状态参数有误'}, status=status.HTTP_400_BAD_REQUEST)
            instance.is_active = is_active
        if str(is_developer):
            if str(is_developer) not in ['0', '1']:
                return Response({'error': '开发者参数有误'}, status=status.HTTP_400_BAD_REQUEST)
            instance.is_developer = is_developer
            if str(is_developer) == '1':
                if not instance.public_key:
                    public_key, private_key = rsa.newkeys(2048)
                    rsa_pem_public_key = public_key.save_pkcs1().decode("utf-8")
                    rsa_der_public_key = private_key.save_pkcs1().decode("utf-8")
                    authen_key = random_str(32)
                    instance.authen_key = authen_key
                    instance.public_key = rsa_pem_public_key
                    instance.private_key = rsa_der_public_key
        if role_id:
            if user.id != 1:
                if str(role_id) not in ['2', '3', '4', '5']:
                    return Response({'error': '无效角色id'}, status=status.HTTP_400_BAD_REQUEST)
            instance.role_id = role_id
        if mobile and mobile != instance.mobile:
            if not re.match(r'^1[3-9]\d{9}$', mobile):
                return Response({"error": "您输入的手机号格式不正确"}, status=status.HTTP_400_BAD_REQUEST)
            user = User.objects.filter(mobile=mobile)
            if user:
                return Response({"error": "手机号码重复"}, status=status.HTTP_400_BAD_REQUEST)
            instance.mobile = mobile
        if username:
            instance.username = username
            instance.nickname = username
        instance.save()
        return Response({"success": "修改成功"}, status=status.HTTP_200_OK)

    def export_manageruser(self, request):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        is_active = self.request.query_params.get('is_active', None)
        role_id = self.request.query_params.get('role_id', None)
        search = self.request.query_params.get('search', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE id!=1'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        if search:
            condition = condition + f' AND (username LIKE "%{search}%" OR mobile LIKE "%{search}%" OR nickname LIKE "%{search}%")'
        if is_active:
            condition = condition + f' AND is_active IN ({is_active})'
        if role_id:
            condition = condition + f' AND role_id IN ({role_id})'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        sql = f'''
        SELECT e.*,f.create_username FROM (SELECT c.*,d.role_name FROM (SELECT a.*,b.prov_name,city_name,district_name,branch_name FROM (SELECT id,username,mobile,is_active,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,level_id,role_id,create_user_id FROM tb_u_user {condition})AS a LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT id,name AS role_name FROM tb_u_role)AS d ON c.role_id=d.id)AS e LEFT JOIN (SELECT id,username AS create_username FROM tb_u_user)AS f ON e.create_user_id=f.id;
        '''
        cursor.execute(sql)
        ziduan = ['id', '角色', '在离岗状态', '姓名', '手机号码', '所属网点', '所属区县', '所属市公司', '所属省公司', '创建人', '创建时间']
        cols = ['id', 'role_name', 'is_active', 'username', 'mobile', 'branch_name', 'district_name', 'city_name', 'prov_name', 'create_username', 'create_time']
        response = StreamingHttpResponse(self.get_manageruser_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('订单列表.csv'))
        return response

    def get_manageruser_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        IS_ACTIVE_ENUM = {
            0: '离岗',
            1: '在岗',
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'is_active':
                    tmp_str += '"%s",' % (IS_ACTIVE_ENUM[row[col]])
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"


class ActivityDataModelViewSet(ModelViewSet):
    '''派发'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    # search_fields = ('username', 'mobile', 'nickname')
    filter_class = ActivityDataFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = ActivityData.objects.all().order_by('-create_time')
        elif level.level == 1:
            queryset = ActivityData.objects.filter(level__prov_id=level.id).order_by('-create_time')
        elif level.level == 2:
            queryset = ActivityData.objects.filter(level__city_id=level.id).order_by('-create_time')
        elif level.level == 3:
            queryset = ActivityData.objects.filter(level__district_id=level.id).order_by('-create_time')
        else:
            queryset = ActivityData.objects.filter(level__branch_id=level.id).order_by('-create_time')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return ActivityDataListModelSerializer
        else:
            return ActivityDataRetrieveModelSerializer


class LevelModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', 'account')
    filter_class = LevelFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return LevelListSerializer
        else:
            return LevelRetrieveSerializer

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        goods_id = self.request.query_params.get('goods_id', None)
        activity_id = self.request.query_params.get('activity_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = Level.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id).order_by('level')
        else:
            queryset = Level.objects.filter(branch_id=level.id).order_by('level')
        if goods_id:
            goods = Goods.objects.filter(id=goods_id).first()
            if goods:
                queryset = queryset.filter(merchantenter__merchant_id=goods.merchant_id).exclude(launchedgoods__goods_id=goods_id).filter(level=4)
        if activity_id:
            level_id_list = list(AliDiscountCouponLevel.objects.filter(activity_id=activity_id).values_list('level_id', flat=True))
            queryset = queryset.filter(id__in=level_id_list)
        return queryset

    def export_level(self, request):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        search = self.request.query_params.get('search', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE level!=0'
        elif level.level == 1:
            condition = f'WHERE prov_id={level.id}'
        elif level.level == 2:
            condition = f'WHERE city_id={level.id}'
        elif level.level == 3:
            condition = f'WHERE district_id={level.id}'
        else:
            condition = f'WHERE branch_id={level.id}'
        if search:
            condition = condition + f' AND (name LIKE "%{search}%" OR account LIKE "%{search}%" )'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT * FROM tb_u_level {condition};
            '''
            cursor.execute(sql)
        except Exception as e:
            sql = f'''
            SELECT * FROM tb_u_level;
            '''
            cursor.execute(sql)
        ziduan = ['id', '机构名称', '组织机构id', '微邮付机构id', '机构号(8位)', '机构号(9位)', '省', '市', '区/县', '网点', '地址', '经度', '维度']
        cols = ['id', 'name', 'orgId', 'acceptId', 'account', 'account_nine', 'prov_name', 'city_name', 'district_name', 'branch_name', 'address', 'longitude', 'latitude']
        response = StreamingHttpResponse(self.get_level_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('订单列表.csv'))
        return response

    def get_level_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col in ['orgId', 'account']:
                    tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        longitude = self.request.data.get('longitude', None)
        latitude = self.request.data.get('latitude', None)
        address = self.request.data.get('address', None)
        telephone = self.request.data.get('telephone', None)
        if longitude and latitude:
            instance.latitude = latitude
            instance.longitude = longitude
        if address:
            instance.address = address
        if telephone:
            instance.telephone = telephone
        instance.save()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)


class ActivityModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', )
    serializer_class = ActivityListSerializer

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = Activity.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Activity.objects.filter(level__prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Activity.objects.filter(level__city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Activity.objects.filter(level__district_id=level.id).order_by('level')
        else:
            queryset = Activity.objects.filter(level__branch_id=level.id).order_by('level')
        return queryset


class MerchantModelViewSet(ModelViewSet):
    '''商户'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', 'wyfMerchantID', 'managerName', 'managermobile')
    filter_class = MerchantFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = Merchant.objects.all().order_by('-create_time')
        elif level.level == 1:
            queryset = Merchant.objects.filter(level__prov_id=level.id).order_by('-create_time')
        elif level.level == 2:
            queryset = Merchant.objects.filter(level__city_id=level.id).order_by('-create_time')
        elif level.level == 3:
            queryset = Merchant.objects.filter(level__district_id=level.id).order_by('-create_time')
        else:
            queryset = Merchant.objects.filter(level__branch_id=level.id).order_by('-create_time')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return MerchantListModelSerializer
        else:
            return MerchantRetrieveModelSerializer

    def branch_info(self, request):
        merchant_id = self.request.query_params.get('merchant_id', None)
        if not merchant_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=merchant_id)
        except:
            return Response({'error': '无效参数'}, status=status.HTTP_400_BAD_REQUEST)
        queryset = instance.merchantenter_set.all()
        page = self.paginate_queryset(queryset)
        data = MerchantEnterModelSerializer(page, many=True).data
        return self.get_paginated_response(data)

    def goods_info(self, request):
        merchant_id = self.request.query_params.get('merchant_id', None)
        if not merchant_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=merchant_id)
        except:
            return Response({'error': '无效参数'}, status=status.HTTP_400_BAD_REQUEST)
        queryset = instance.goods_set.all()
        page = self.paginate_queryset(queryset)
        data = GoodsListModelSerializer(page, many=True).data
        return self.get_paginated_response(data)

    def check_merchant(self, request):
        user = self.request.iser
        business_no = self.request.data.get('business_no', None)
        if not business_no:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        business_no = str(business_no).replace(' ', '')
        if not business_no.isdigit() and len(business_no) != 10:
            return Response({'error': '请输入10位纯数字微邮付商户号'}, status=status.HTTP_400_BAD_REQUEST)
        md5 = hashlib.md5()  # 使用MD5加密模式
        md5.update(str(business_no).encode('utf-8'))  # 将参数字符串传入
        sign = md5.hexdigest()  # 完成加密并转为大写
        url = 'https://manage.gdwxyf.com/internal/searchmerchantbyshopids.do'
        body = {
            'account': 'gdyouzheng',
            'shopId': sign
        }
        reaponse = requests.post(url=url, data=body)
        try:
            reaponse = reaponse.json()
        except:
            return Response({'error': '系统繁忙,请重新操作'}, status=status.HTTP_400_BAD_REQUEST)
        if 'wx_channel_merchant_id' not in reaponse:
            return Response({'error': '商户号有误,请检查重新操作'}, status=status.HTTP_400_BAD_REQUEST)
        if reaponse['wx_channel_merchant_id'] == '':
            return Response({'error': '获取商户信息失败，请确认该商户是否审核成功。'}, status=status.HTTP_400_BAD_REQUEST)
        merchant = Merchant.objects.filter(wyfMerchantID=business_no).first()
        if merchant:
            merchantchannel_data = {
                'merchant_id': merchant.id
            }
            if reaponse['allchannelJson']['channel_ruiyinxin']:
                if reaponse['allchannelJson']['channel_ruiyinxin']['status'] == 1:
                    merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_4']
                    merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_7']
                    merchantchannel_data['channel_id'] = 2
                    merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_3']
                    MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
            if reaponse['allchannelJson']['channel_sxf_tq']:
                if reaponse['allchannelJson']['channel_sxf_tq']['status'] == 1:
                    merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_4'] if 'merchant_other_4' in reaponse['allchannelJson']['channel_sxf_tq'] else ''
                    merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_no']
                    merchantchannel_data['channel_id'] = 3
                    merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_3']
                    MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
            if reaponse['channel_mch_id'] == '227823797':
                try:
                    channel_url = 'https://manage.gdwxyf.com/internal/searchmerchantchannelmsg.do'
                    channel_body = {"account": "gdyouzheng", "shopId": sign}
                    channel_response = requests.post(url=channel_url, data=channel_body)
                    channel_result = channel_response.json()
                    merchantchannel_data['smid'] = channel_result['alipaychannelJson']['merchant_other_4'] if 'merchant_other_4' in channel_result['alipaychannelJson'] else ''
                    merchantchannel_data['channel_mchid'] = channel_result['alipaychannelJson']['upMerchantNo']
                    merchantchannel_data['channel_id'] = 15
                    merchantchannel_data['sub_mchid'] = channel_result['wxchannelJson']['merchant_other_3']
                    MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                except:
                    pass
        else:
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    merchant_data = {}
                    channel_mch_id = reaponse['channel_mch_id']
                    channel = Channel.objects.filter(mchid=channel_mch_id).first()
                    if channel:
                        merchant_data['channel_id'] = channel.id
                    merchant_data['name'] = reaponse['shopName']
                    merchant_data['short_name'] = reaponse['shopNickname']
                    merchant_data['wyfMerchantID'] = business_no
                    merchant_data['ruiyinxinMerchantID'] = sign
                    merchant_data['create_time'] = datetime.datetime.now()
                    if reaponse['businessType'] == '1':
                        merchant_data['subject_type'] = 3
                    elif reaponse['businessType'] == '2':
                        merchant_data['subject_type'] = 2
                    elif reaponse['businessType'] == '3':
                        merchant_data['subject_type'] = 1
                    else:
                        merchant_data['subject_type'] = 4
                    level = Level.objects.filter(acceptId=reaponse['accept_id']).first()
                    if level:
                        merchant_data['level_id'] = level.id
                    merchantuser, create = MerchantUser.objects.get_or_create(mobile=reaponse['phone'], defaults={"mobile": reaponse['phone'], 'level_id': level.id if level else None})
                    merchant_data['merchantuser_id'] = merchantuser.id
                    merchant_data['account_name'] = reaponse['cardName']
                    merchant_data['account_bank'] = reaponse['bankName']
                    merchant_data['account_number'] = reaponse['card']
                    if 'latitude' in reaponse:
                        merchant_data['latitude'] = reaponse['latitude']
                    if 'longitude' in reaponse:
                        merchant_data['longitude'] = reaponse['longitude']
                    card_copy = f'youhuiquanyi/{business_no}/card_copy.png'
                    card_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/cardFace.png', key=card_copy)
                    if card_copy_url:
                        merchant_data['card_copy'] = card_copy
                    merchant_data['identification_number'] = reaponse['identity']
                    merchant_data['store_address'] = reaponse['address']
                    store_header_copy = f'youhuiquanyi/{business_no}/store_header_copy.png'
                    store_header_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantHead.png', key=store_header_copy)
                    if store_header_copy_url:
                        merchant_data['store_header_copy'] = store_header_copy
                    merchant, cereate = Merchant.objects.update_or_create(defaults=merchant_data, wyfMerchantID=business_no)
                    if not merchant.managerName:
                        merchant.managerName = reaponse['keeper']
                    if not merchant.managermobile:
                        merchant.managermobile = reaponse['phone']
                    if not merchant.prov_name:
                        merchant.prov_name = reaponse['province']
                        merchant.city_name = reaponse['city']
                        merchant.district_name = reaponse['area']
                    if not merchant.business_category:
                        merchant.business_category_id = 1
                    if not merchant.store_logo_copy:
                        merchant.store_logo_copy = 'default_merchant_logo.jpg'
                    merchant.save()
                    if cereate and merchant.channel:
                        store_header_copy = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        store_header_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantHead.png', key=store_header_copy)
                        if store_header_copy_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=store_header_copy)
                        store_indoor_copy = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        store_indoor_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/otherPhoto3.png', key=store_indoor_copy)
                        if store_indoor_copy_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=store_indoor_copy)
                        merchantCheck = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                        merchantCheck_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantCheck.png', key=merchantCheck)
                        if merchantCheck_url:
                            MerchantImage.objects.create(merchant_id=merchant.id, image=merchantCheck)
                    merchantchannel_data = {
                        'merchant_id': merchant.id
                    }
                    if reaponse['allchannelJson']['channel_ruiyinxin']:
                        if reaponse['allchannelJson']['channel_ruiyinxin']['status'] == 1:
                            merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_4']
                            merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_7']
                            merchantchannel_data['channel_id'] = 2
                            merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                    if reaponse['allchannelJson']['channel_sxf_tq']:
                        if reaponse['allchannelJson']['channel_sxf_tq']['status'] == 1:
                            merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_4'] if 'merchant_other_4' in reaponse['allchannelJson']['channel_sxf_tq'] else ''
                            merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_no']
                            merchantchannel_data['channel_id'] = 3
                            merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_sxf_tq']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                    if reaponse['channel_mch_id'] == '227823797':
                        try:
                            channel_url = 'https://manage.gdwxyf.com/internal/searchmerchantchannelmsg.do'
                            channel_body = {"account": "gdyouzheng", "shopId": sign}
                            channel_response = requests.post(url=channel_url, data=channel_body)
                            channel_result = channel_response.json()
                            merchantchannel_data['smid'] = channel_result['alipaychannelJson']['merchant_other_4'] if 'merchant_other_4' in channel_result['alipaychannelJson'] else ''
                            merchantchannel_data['channel_mchid'] = channel_result['alipaychannelJson']['upMerchantNo']
                            merchantchannel_data['channel_id'] = 15
                            merchantchannel_data['sub_mchid'] = channel_result['wxchannelJson']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchantchannel_data['channel_id'])
                        except:
                            pass
                    transaction.savepoint_commit(save_id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '获取商户信息错误,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        data = MerchantRetrieveModelSerializer(merchant).data
        return Response(data, status=status.HTTP_200_OK)

    def batch_check_merchant(self, request):
        user = self.request.iser
        # business_no = self.request.data.get('business_no', None)
        # if not business_no:
        #     return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        # business_no = str(business_no).replace(' ', '')
        # if not business_no.isdigit() and len(business_no) != 10:
        #     return Response({'error': '请输入10位纯数字微邮付商户号'}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn = get_redis_connection("stock_mchid")
        is_run_server = redis_conn.get("is_run")
        if is_run_server:
            return Response({'error': "有正在执行的任务,请稍候"}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn.set("is_run", 1)
        my_file = self.request.FILES.get('my_file', None)
        user = self.request.iser
        if not my_file:
            redis_conn.delete("is_run")
            return Response({'error': '请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        type_excel = my_file.name.split('.')[-1]
        file_contents = my_file.read()
        if type_excel not in ['xlsx', 'xls']:
            redis_conn.delete("is_run")
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            wb = xlrd.open_workbook(filename=None, file_contents=file_contents)  # 关键点在于这里
        except:
            redis_conn.delete("is_run")
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        table = wb.sheets()[0]
        title = table.row_values(0)
        if '批次号' not in title:
            redis_conn.delete("is_run")
            return Response({'error': '表格字段缺少"批次号"'}, status=status.HTTP_400_BAD_REQUEST)
        if '商户号' not in title:
            redis_conn.delete("is_run")
            return Response({'error': '表格字段缺少"商户号"'}, status=status.HTTP_400_BAD_REQUEST)
        business_no_index = title.index('商户号')
        stock_index = title.index('批次号')
        nrows = table.nrows
        data = {}
        cookies = Channel.objects.get(id=4)
        headers = {'Cookie': cookies.cookie}
        business_no_list = list(Merchant.objects.all().values_list('wyfMerchantID', flat=True))
        for i in range(1, nrows):
            rowValues = table.row_values(i)
            business_no = str(rowValues[business_no_index]).replace('.0', '').replace(' ', '')
            if not business_no.isdigit() and len(business_no) != 10:
                return Response({'error': '请输入10位纯数字微邮付商户号'}, status=status.HTTP_400_BAD_REQUEST)
        # merchant = Merchant.objects.filter(wyfMerchantID=business_no).first()
        # if merchant:
        #     pass
        # else:
        md5 = hashlib.md5()  # 使用MD5加密模式
        md5.update(str(business_no).encode('utf-8'))  # 将参数字符串传入
        sign = md5.hexdigest()  # 完成加密并转为大写
        url = 'https://manage.gdwxyf.com/internal/searchmerchantbyshopids.do'
        body = {
            'account': 'gdyouzheng',
            'shopId': sign
        }
        reaponse = requests.post(url=url, data=body)
        try:
            reaponse = reaponse.json()
        except:
            return Response({'error': '系统繁忙,请重新操作'}, status=status.HTTP_400_BAD_REQUEST)
        if 'wx_channel_merchant_id' not in reaponse:
            return Response({'error': '商户号有误,请检查重新操作'}, status=status.HTTP_400_BAD_REQUEST)
        if reaponse['wx_channel_merchant_id'] == '':
            return Response({'error': '获取商户信息失败，请确认该商户是否审核成功。'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                merchant_data = {}
                channel_mch_id = reaponse['channel_mch_id']
                channel = Channel.objects.filter(mchid=channel_mch_id).first()
                if channel:
                    merchant_data['channel_id'] = channel.id
                merchant_data['name'] = reaponse['shopName']
                merchant_data['short_name'] = reaponse['shopNickname']
                merchant_data['wyfMerchantID'] = business_no
                merchant_data['ruiyinxinMerchantID'] = sign
                merchant_data['create_time'] = datetime.datetime.now()
                if reaponse['businessType'] == '1':
                    merchant_data['subject_type'] = 3
                elif reaponse['businessType'] == '2':
                    merchant_data['subject_type'] = 2
                elif reaponse['businessType'] == '3':
                    merchant_data['subject_type'] = 1
                else:
                    merchant_data['subject_type'] = 4
                level = Level.objects.filter(acceptId=reaponse['accept_id']).first()
                if level:
                    merchant_data['level_id'] = level.id
                merchantuser = MerchantUser.objects.filter(mobile=reaponse['phone']).first()
                if merchantuser:
                    merchant_data['merchantuser_id'] = merchantuser.id
                merchant_data['account_name'] = reaponse['cardName']
                merchant_data['account_bank'] = reaponse['bankName']
                merchant_data['account_number'] = reaponse['card']
                card_copy = f'youhuiquanyi/{business_no}/card_copy.png'
                card_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/cardFace.png', key=card_copy)
                if card_copy_url:
                    merchant_data['card_copy'] = card_copy
                merchant_data['identification_number'] = reaponse['identity']
                merchant_data['store_address'] = reaponse['address']
                store_header_copy = f'youhuiquanyi/{business_no}/store_header_copy.png'
                store_header_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantHead.png', key=store_header_copy)
                if store_header_copy_url:
                    merchant_data['store_header_copy'] = store_header_copy
                merchant, cereate = Merchant.objects.update_or_create(defaults=merchant_data, wyfMerchantID=business_no)
                if not merchant.managerName:
                    merchant.managerName = reaponse['keeper']
                if not merchant.managermobile:
                    merchant.managermobile = reaponse['phone']
                if not merchant.prov_name:
                    merchant.prov_name = reaponse['province']
                    merchant.city_name = reaponse['city']
                    merchant.district_name = reaponse['area']
                if not merchant.business_category:
                    merchant.business_category_id = 1
                if not merchant.store_logo_copy:
                    merchant.store_logo_copy = 'default_merchant_logo.jpg'
                merchant.save()
                if cereate and merchant.channel:
                    store_header_copy = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                    store_header_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantHead.png', key=store_header_copy)
                    if store_header_copy_url:
                        MerchantImage.objects.create(merchant_id=merchant.id, image=store_header_copy)
                    store_indoor_copy = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                    store_indoor_copy_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/otherPhoto3.png', key=store_indoor_copy)
                    if store_indoor_copy_url:
                        MerchantImage.objects.create(merchant_id=merchant.id, image=store_indoor_copy)
                    merchantCheck = f'youhuiquanyi/{business_no}/merchant_image{"%06d" % randint(0, 999999)}.png'
                    merchantCheck_url = sync_img_to_local(f'http://ossmerchant.gdwxyf.com/{sign}/merchantCheck.png', key=merchantCheck)
                    if merchantCheck_url:
                        MerchantImage.objects.create(merchant_id=merchant.id, image=merchantCheck)
                    merchantchannel_data = {
                        'merchant_id': merchant.id
                    }
                    if merchant.channel_id != 2:
                        if reaponse['allchannelJson']['channel_ruiyinxin']:
                            merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_4']
                            merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_7']
                            merchantchannel_data['channel_id'] = 2
                            merchantchannel_data['sub_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchant.channel_id)
                            channel_response = requests.post(
                                url='https://manage.gdwxyf.com/internal/searchmerchant.do',
                                data={'shopId': business_no, 'account': 'gdyouzheng'},
                            ).json()['showList'][0]
                            merchantchannel_data['smid'] = channel_response['allchannelJson']['channel_sxf_tq']['shop_merchant_other_4']
                            merchantchannel_data['channel_mchid'] = channel_response['allchannelJson']['channel_sxf_tq']['shop_merchant_no']
                            merchantchannel_data['channel_id'] = 3
                            merchantchannel_data['sub_mchid'] = channel_response['allchannelJson']['channel_sxf_tq']['shop_merchant_other_3']
                            MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchant.channel_id)
                    else:
                        merchantchannel_data['smid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_4']
                        merchantchannel_data['channel_mchid'] = reaponse['allchannelJson']['channel_ruiyinxin']['merchant_other_7']
                        merchantchannel_data['channel_id'] = merchant.channel_id
                        merchantchannel_data['sub_mchid'] = reaponse['wx_channel_merchant_id']
                        MerchantChannel.objects.get_or_create(defaults=merchantchannel_data, merchant_id=merchant.id, channel_id=merchant.channel_id)
                transaction.savepoint_commit(save_id)
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '获取商户信息错误,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        data = MerchantRetrieveModelSerializer(merchant).data
        return Response(data, status=status.HTTP_200_OK)

    def update_logo(self, request):
        user = self.request.iser
        img = self.request.FILES.get('img', None)
        merchant_id = self.request.data.get('merchant_id', None)
        if not all([img, merchant_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户号'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            img_id = f'youhuiquanyi/{merchant.wyfMerchantID}/store_logo_copy{"%06d" % randint(0, 999999)}.png'
            mid_img = pic_upload(img_str, key=img_id)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            old_store_logo_copy = merchant.store_logo_copy
            pic_delete(old_store_logo_copy)
        except:
            pass
        merchant.store_logo_copy = img_id
        merchant.save()
        merchant = Merchant.objects.get(id=merchant.id)
        return Response({'success': '操作成功', 'store_logo_copy': merchant.store_logo_copy.url}, status=status.HTTP_200_OK)

    def delete_image(self, request):
        user = self.request.iser
        img_id = self.request.data.get('img_id', None)
        instance = MerchantImage.objects.filter(id=img_id).first()
        try:
            old_store_logo_copy = instance.image
            pic_delete(old_store_logo_copy)
        except:
            pass
        instance.delete()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def add_image(self, request):
        user = self.request.iser
        img = self.request.FILES.get('img', None)
        merchant_id = self.request.data.get('merchant_id', None)
        if not all([img, merchant_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户号'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            img_id = f'youhuiquanyi/{merchant.wyfMerchantID}/merchant_image{"%06d" % randint(0, 999999)}.png'
            mid_img = pic_upload(img_str, key=img_id)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        instance = MerchantImage.objects.create(merchant_id=merchant.id, image=img_id)
        data = MerchantImageSerializer(instance).data
        return Response({'success': '操作成功', 'img': data}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        managerName = self.request.data.get('managerName', None)
        managermobile = self.request.data.get('managermobile', None)
        short_name = self.request.data.get('short_name', None)
        merchant_desc = self.request.data.get('merchant_desc', None)
        business_category_id = self.request.data.get('business_category_id', None)
        open_work_time = self.request.data.get('open_work_time', None)
        close_work_time = self.request.data.get('close_work_time', None)
        longitude = self.request.data.get('longitude', None)
        latitude = self.request.data.get('latitude', None)
        store_address = self.request.data.get('store_address', None)
        is_online = self.request.data.get('is_online', None)
        prov_name = self.request.data.get('prov_name', None)
        city_name = self.request.data.get('city_name', None)
        district_name = self.request.data.get('district_name', None)
        prov_code = self.request.data.get('prov_code', None)
        city_code = self.request.data.get('city_code', None)
        district_code = self.request.data.get('district_code', None)
        settlement_amount_by_day = self.request.data.get('settlement_amount_by_day', None)
        if managerName:
            instance.managerName = managerName
        if settlement_amount_by_day:
            instance.settlement_amount_by_day = settlement_amount_by_day
        if managermobile:
            merchantuser, create = MerchantUser.objects.get_or_create(mobile=managermobile, defaults={"mobile": managermobile})
            instance.merchantuser_id = merchantuser.id
            instance.managermobile = managermobile
            try:
                WaivePaymentMerchant.objects.filter(merchant_id=instance.id).update(merchant_user_id=merchantuser.id)
            except:
                pass
            conn = pymysql.connect(host=settings.DATABASES['open']['HOST'],
                                   port=settings.DATABASES['open']['PORT'],
                                   database=settings.DATABASES['open']['NAME'],
                                   user=settings.DATABASES['open']['USER'],
                                   password=settings.DATABASES['open']['PASSWORD'])
            cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
            try:
                sql = f'''UPDATE tb_m_merchant_info SET mobile={managermobile} WHERE merchant_id IN (SELECT id FROM tb_m_merchant WHERE business_no={instance.wyfMerchantID});'''
                cursor.execute(sql)
                sql = f'''SELECT id FROM tb_m_merchant_user WHERE mobile={managermobile};'''
                cursor.execute(sql)
                row = cursor.fetchone()
                if row is not None:
                    merchant_user_id = row['id']
                    sql = f'''UPDATE tb_m_merchant SET merchant_user_id={merchant_user_id} WHERE business_no={instance.wyfMerchantID};'''
                    cursor.execute(sql)
                else:
                    sql = f'''UPDATE tb_m_merchant SET merchant_user_id=null WHERE business_no={instance.wyfMerchantID};'''
                    cursor.execute(sql)
                conn.commit()
            except Exception as e:
                print(e)
                conn.rollback()
            cursor.close()
            conn.close()
        if short_name:
            instance.short_name = short_name
        if merchant_desc:
            instance.merchant_desc = merchant_desc
        if business_category_id:
            try:
                business_category = MerchantBusinessCategory.objects.get(id=business_category_id)
            except:
                return Response({'error': '无效经营类目'}, status=status.HTTP_400_BAD_REQUEST)
            instance.business_category_id = business_category_id
        if open_work_time:
            try:
                time.strptime(str(open_work_time), "%H:%M")
            except:
                return Response({'error': '经营时间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
            busStartTm = f'1900-01-01 {open_work_time}:00'
            instance.open_work_time = busStartTm
        if close_work_time:
            try:
                time.strptime(str(close_work_time), "%H:%M")
            except:
                return Response({'error': '经营时间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
            busEndTm = f'1900-01-01 {close_work_time}:00'
            instance.close_work_time = busEndTm
        if longitude:
            instance.longitude = longitude
        if latitude:
            instance.latitude = latitude
        if prov_name:
            instance.prov_name = prov_name
        if city_name:
            instance.city_name = city_name
        if district_name:
            instance.district_name = district_name
        if prov_code:
            instance.prov_code = prov_code
        if city_code:
            instance.city_code = city_code
        if district_code:
            instance.district_code = district_code
        if store_address:
            instance.store_address = store_address
        if is_online:
            if str(is_online) not in ['1', '2', '3']:
                return Response({'error': '上下架参数有误'}, status=status.HTTP_400_BAD_REQUEST)
            instance.is_online = is_online
        try:
            instance.save()
            return Response({'success': '保存成功'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '保存失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def partial_update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        enter_array = self.request.data.get('enter_array', None)
        if not enter_array:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(enter_array, list):
            return Response({'error': '参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        for enter in enter_array:
            enter_data = {}
            try:
                level = Level.objects.get(id=enter['level_id'])
                if level.level != 4:
                    continue
                if str(enter['is_online']) not in ['2', '3']:
                    continue
                enter_data['level_id'] = enter['level_id']
                enter_data['managerName'] = enter['managerName']
                enter_data['managermobile'] = enter['managermobile']
                enter_data['is_online'] = enter['is_online']
                enter_data['merchant_id'] = instance.id
                enter_data['user_id'] = user.id
                enter_data['create_time'] = datetime.datetime.now()
                MerchantEnter.objects.update_or_create(defaults=enter_data, level_id=enter_data['level_id'], merchant_id=enter_data['merchant_id'])
            except:
                continue
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def enter_level(self, request):
        user = self.request.iser
        level = user.level
        search = self.request.query_params.get('search', None)
        merchant_id = self.request.query_params.get('merchant_id', None)
        if not merchant_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        if level.level == 0:
            queryset = Level.objects.filter(level=4)
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id, level=4)
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id, level=4)
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id, level=4)
        else:
            queryset = Level.objects.filter(branch_id=level.id, level=4)
        if search:
            # queryset = queryset.filter(Q(name__contains=search) | Q(account__contains=search))
            try:
                search = search.replace('，', ',')
                search = search.split(',')
                if '' in search:
                    search.remove('')
                queryset = queryset.filter(account__in=search)
            except:
                pass
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = EnterLvelModelSerializer(page, many=True, context={'merchant': merchant})
            return self.get_paginated_response(serializer.data)

        serializer = EnterLvelModelSerializer(queryset, many=True, context={'merchant': merchant})
        return Response(serializer.data)

    def export_merchant(self, request):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        create_time_begin = self.request.query_params.get('create_time_begin', None)
        create_time_end = self.request.query_params.get('create_time_end', None)
        search = self.request.query_params.get('search', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE id!=0'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        if search:
            condition = condition + f' AND (name LIKE "%{search}%" OR short_name LIKE "%{search}%" OR wyfMerchantID LIKE "%{search}%")'
        if create_time_begin:
            condition = condition + f' AND create_time >= "{create_time_begin + " 00:00:00"}"'
        if create_time_end:
            condition = condition + f' AND create_time <= "{create_time_end + " 23:59:59"}"'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT c.*,d.account,city_name,district_name,branch_name FROM (SELECT * FROM (SELECT id,wyfMerchantID,managerName,name,level_id,settlement_amount_by_day FROM tb_merchant {condition})AS a LEFT JOIN (SELECT merchant_id,MAX(CASE channel_id WHEN 2 THEN sub_mchid ELSE '' END)AS ryx_sub_mchid,MAX(CASE channel_id WHEN 2 THEN smid ELSE '' END)AS ryx_smid,MAX(CASE channel_id WHEN 3 THEN sub_mchid ELSE '' END)AS sxf_sub_mchid,MAX(CASE channel_id WHEN 3 THEN smid ELSE '' END)AS sxf_smid FROM tb_merchant_channel WHERE merchant_id IN (SELECT id FROM tb_merchant {condition}) GROUP BY merchant_id)AS b ON a.id=b.merchant_id)AS c LEFT JOIN (SELECT id,account,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id;
            '''
            cursor.execute(sql)
        except Exception as e:
            sql = f'''
            SELECT c.*,d.account,city_name,district_name,branch_name FROM (SELECT * FROM (SELECT id,wyfMerchantID,managerName,name,level_id,settlement_amount_by_day FROM tb_merchant)AS a LEFT JOIN (SELECT merchant_id,MAX(CASE channel_id WHEN 2 THEN sub_mchid ELSE '' END)AS ryx_sub_mchid,MAX(CASE channel_id WHEN 2 THEN smid ELSE '' END)AS ryx_smid,MAX(CASE channel_id WHEN 3 THEN sub_mchid ELSE '' END)AS sxf_sub_mchid,MAX(CASE channel_id WHEN 3 THEN smid ELSE '' END)AS sxf_smid FROM tb_merchant_channel GROUP BY merchant_id)AS b ON a.id=b.merchant_id)AS c LEFT JOIN (SELECT id,account,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id;
            '''
            cursor.execute(sql)
        ziduan = ['id', '微邮付商户号', '商户简称', '商户全称', '瑞银信间连微信商户号', '瑞银信支付宝商户号', '随行付间连微信商户号', '随行付支付宝商户号', '网点机构号', '所属市公司', '所属区县', '所属网点', '结算限额/天']
        cols = ['id', 'wyfMerchantID', 'managerName', 'name', 'ryx_sub_mchid', 'ryx_smid', 'sxf_sub_mchid', 'sxf_smid', 'account', 'city_name', 'district_name', 'branch_name', 'settlement_amount_by_day']
        response = StreamingHttpResponse(self.get_merchant_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('商户列表.csv'))
        return response

    def get_merchant_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col in ['ryx_smid', 'sxf_smid']:
                    tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def is_add_merchant(self, request):
        redis_conn = get_redis_connection("stock_mchid")
        is_run_server = redis_conn.get("is_add_merchant")
        if is_run_server:
            return Response({'state': "1"}, status=status.HTTP_200_OK)
        else:
            return Response({'state': "0"}, status=status.HTTP_200_OK)

    def add_merchant(self, request):
        redis_conn = get_redis_connection("stock_mchid")
        is_run_server = redis_conn.get("is_add_merchant")
        if is_run_server:
            return Response({'error': "有正在执行的任务,请稍候"}, status=status.HTTP_400_BAD_REQUEST)
        business_no_array = self.request.data.get('business_no_array', None)
        if not isinstance(business_no_array, list):
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        if len(business_no_array) > 1000:
            return Response({'error': '最大不能超过1000商户同时同步'}, status=status.HTTP_400_BAD_REQUEST)
        redis_conn.set("is_add_merchant", 1)
        add_merchant_array.delay({'business_no_array': business_no_array})
        return Response({'success': '提交修改成功,等待系统处理'}, status=status.HTTP_200_OK)

    def open_is_mall(self, request):
        merchant_id = self.request.query_params.get('merchant_id', None)
        if not merchant_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        merchant = self.get_queryset().filter(id=merchant_id).first()
        if not merchant:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall != 0:
            return Response({'error': '商户商圈状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        '''校验商户当前通道'''
        try:
            url = 'https://api.gdwxyf.com/api/searchmerchantmsg.do'
            key = '6715C7D4435343BA0459EAEC2334D81B'
            body = {
                "program_id": "202316837141378884",
                "shop_id": merchant.wyfMerchantID
            }
            sign = get_sign(body, key)
            body['sign'] = sign
            response = requests.post(url=url, json=body)
            result = response.json()
            if result['pay_type'] != 'sxf_tq':
                return Response({'error': '商户通道不支持入驻商圈'}, status=status.HTTP_400_BAD_REQUEST)
        except:
            pass
        if merchant.channel_id != 3:
            return Response({'error': '商户通道不支持入驻商圈'}, status=status.HTTP_400_BAD_REQUEST)
        '''商户授权应用id'''
        url = 'https://api.gdwxyf.com/api/shopBindApp.do'
        key = '6715C7D4435343BA0459EAEC2334D81B'
        body = {
            "program_id": "202316837141378884",
            "shop_id": merchant.wyfMerchantID
        }
        sign = get_sign(body, key)
        body['sign'] = sign
        response = requests.post(url=url, json=body)
        result = response.json()
        if result['result_code'] != 'success' and result['error_msg'] != '商户与应用已绑定，请勿重复绑定。':
            return Response({'error': result['error_msg']}, status=status.HTTP_400_BAD_REQUEST)
        '''商户绑定授权appid'''
        url = 'https://api.gdwxyf.com/api/setMerchantWxAppMsg.do'
        body = {
            "program_id": "202316837141378884",
            "shop_id": merchant.ruiyinxinMerchantID,
            "config_type": 'appid',
            "appid": "wx950122ad80dc97c9"
        }
        sign = get_sign(body, key)
        body['sign'] = sign
        response = requests.post(url=url, json=body)
        result = response.json()
        if result['result_code'] != 'success' and result['error_msg'] != '微信公众号配置已配置':
            return Response({'error': result['error_msg']}, status=status.HTTP_400_BAD_REQUEST)
        merchant.is_mall = 1
        merchant.save()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def confirm_is_mall(self, request):
        user = self.request.iser
        merchant_id = self.request.data.get('merchant_id', None)
        reject_reason = self.request.data.get('reject_reason', None)
        applyment_state = self.request.data.get('applyment_state', None)
        datetime_now = datetime.datetime.now()
        if not merchant_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        merchant = self.get_queryset().filter(id=merchant_id).first()
        if not merchant:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        if merchant.is_mall != 5:
            return Response({'error': '商户商圈状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        mall_applyment = MerchantMallApplyment.objects.filter(merchant_id=merchant.id, applyment_type=1).last()
        if str(applyment_state) == '1':
            # if merchant.applyment_state == 5:
            #     store_indoor_copy = MerchantImage.objects.filter(merchant_id=merchant.id).first()
            #     if not store_indoor_copy:
            #         store_indoor_copy = merchant.store_header_copy.url
            #     else:
            #         store_indoor_copy = store_indoor_copy.image.url
            #     result = submit_sign_contract(merchant.ruiyinxinMerchantID, mall_applyment.contract.url, merchant.store_header_copy.url, store_indoor_copy)
            #     if result['data']['sign_status'] == 1:
            #         merchant.applyment_state = 4
            #         merchant.save()
            #         mall_applyment.applyment_state = 4
            #         signUrl = result['data']['sign_url']
            #         sign_url = make_qrcode1(merchant.ruiyinxinMerchantID, signUrl, key=None)
            #         mall_applyment.sign_url = sign_url
            #         mall_applyment.save()
            #         return Response({'success': '提交资料成功,等待审核'}, status=status.HTTP_200_OK)
            #     else:
            #         return Response({'error': result['data']['message']}, status=status.HTTP_400_BAD_REQUEST)
            # else:
            #     if merchant.applyment_state != 2:
            #         return Response({'error': '请等待商户签约完成再审核'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                '''创建门店'''
                url = 'https://manage.gdwxyf.com/internal/savebranchstoremsg.do'
                body = {
                    "deviceName": "微邮惠商圈",
                    "shopId": merchant.wyfMerchantID,
                    "account": "gdyouzheng"
                }
                response = requests.post(url=url, data=body)
                result = response.json()
                device_id = result['device_id']
                '''绑定设备id'''
                url = 'https://manage.gdwxyf.com/internal/savenewqrcode.do'
                body = {
                    "deviceName": "微邮惠商圈",
                    "shopId": merchant.wyfMerchantID,
                    "wsyDeviceId": f'{merchant.wyfMerchantID}2024',
                    "deviceId": device_id
                }
                response = requests.post(url=url, data=body)
                result = response.json()
                if result['result_code'] == 'fail':
                    return Response({'error': result['error_msg']}, status=status.HTTP_400_BAD_REQUEST)
            except:
                return Response({'error': '创建门店失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            merchant.is_mall = 2
            merchant.device = f'{merchant.wyfMerchantID}2024'
            merchant.applyment_state = 2
            merchant.verify_state = 2
            merchant.is_profit_share = 4
            merchant.save()
            if mall_applyment:
                mall_applyment.applyment_state = 2
                mall_applyment.audit_time = datetime_now
                mall_applyment.verify_state = 2
                mall_applyment.verify_time = datetime_now
                mall_applyment.verify_user_id = user.id
                mall_applyment.save()
            return Response({'success': '审核成功'}, status=status.HTTP_200_OK)
        elif str(applyment_state) == '2':
            merchant.is_mall = 1
            merchant.applyment_state = 3
            merchant.save()
            if mall_applyment:
                mall_applyment.applyment_state = 3
                mall_applyment.audit_time = datetime_now
                mall_applyment.reject_reason = reject_reason
                mall_applyment.verify_user_id = user.id
                mall_applyment.save()
            return Response({'success': '驳回成功'}, status=status.HTTP_200_OK)
        else:
            return Response({'error': '审核参数有误'}, status=status.HTTP_400_BAD_REQUEST)

    def batch_enter_level(self, request):
        my_file = self.request.FILES.get('my_file', None)
        user = self.request.iser
        if not my_file:
            return Response({'error': '请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        type_excel = my_file.name.split('.')[-1]
        file_contents = my_file.read()
        if type_excel not in ['xlsx', 'xls']:
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            wb = xlrd.open_workbook(filename=None, file_contents=file_contents)  # 关键点在于这里
        except:
            return Response({'error': '文件格式有误, 请上传excel文件'}, status=status.HTTP_400_BAD_REQUEST)
        table = wb.sheets()[0]
        nrows = table.nrows
        title = table.row_values(0)
        if '商户号' not in title:
            return Response({'error': '表格字段缺少"商户号"'}, status=status.HTTP_400_BAD_REQUEST)
        if '机构号' not in title:
            return Response({'error': '表格字段缺少"机构号"'}, status=status.HTTP_400_BAD_REQUEST)
        if '负责人姓名' not in title:
            return Response({'error': '表格字段缺少"负责人姓名"'}, status=status.HTTP_400_BAD_REQUEST)
        if '负责人手机号码' not in title:
            return Response({'error': '表格字段缺少"负责人手机号码"'}, status=status.HTTP_400_BAD_REQUEST)
        file_name = f'{my_file.name.replace(type_excel, "").replace(".", "")}_{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.{type_excel}'
        file = pic_upload(file_contents, file_name)
        check_quest = MerchantEnterQuest.objects.filter(file_status=2)
        if check_quest:
            file_status = 1
        else:
            file_status = 2
        quest = MerchantEnterQuest.objects.create(create_user_id=user.id, file=file, file_status=file_status, total_line=nrows-1)
        if file_status == 2:
            operation_merchant_enter_quest.delay({'id': quest.id})
            # operation_merchant_bank_quest({'id': quest.id})
        return Response({'success': '上传文件成功'}, status=status.HTTP_200_OK)

    def update_merchant_channel(self, request):
        merchant_id = self.request.data.get('merchant_id', None)
        if not merchant_id:
            return Response({'error': '请上传商户id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            merchant = self.get_queryset().get(id=merchant_id)
        except:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            url = 'https://api.gdwxyf.com/api/searchmerchantmsg.do'
            key = '6715C7D4435343BA0459EAEC2334D81B'
            body = {
                "program_id": "202316837141378884",
                "shop_id": merchant.wyfMerchantID
            }
            sign = get_sign(body, key)
            body['sign'] = sign
            response = requests.post(url=url, json=body)
            result = response.json()
            if result['pay_type'] == 'sxf_tq':
                merchant.channel_id = 3
            elif result['pay_type'] == 'ruiyinxin':
                merchant.channel_id = 2
            elif result['pay_type'] == 'guotong':
                merchant.channel_id = 15
            merchant.save()
        except:
            pass
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)


class MerchantBusinessCategoryModelViewSet(ModelViewSet):

    queryset = MerchantBusinessCategory.objects.all()
    serializer_class = MerchantBusinessCategoryModelSerializer


class LaunchedGoodsModelViewSet(ModelViewSet):
    '''商品'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', 'goods__merchant__name', 'level__account', 'level__name')
    filter_class = LaunchedGoodsFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return LaunchedGoodsListModelSerializer
        else:
            return LaunchedGoodsListModelSerializer

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = LaunchedGoods.objects.all()
        elif level.level == 1:
            queryset = LaunchedGoods.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = LaunchedGoods.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = LaunchedGoods.objects.filter(level__district_id=level.id)
        else:
            queryset = LaunchedGoods.objects.filter(level__branch_id=level.id)
        goods_id = self.request.query_params.get('goods_id', None)
        if goods_id:
            goods = Goods.objects.filter(id=goods_id).first()
            if goods:
                check_query = queryset.filter(goods_id=goods_id, is_self=1)
                if not check_query:
                    launched_goods_data = {}
                    launched_goods_data['name'] = goods.name
                    launched_goods_data['caption'] = goods.caption
                    launched_goods_data['goods_id'] = goods.id
                    launched_goods_data['category_id'] = goods.category_id
                    launched_goods_data['price'] = goods.price
                    launched_goods_data['point'] = goods.point
                    launched_goods_data['stock'] = goods.stock
                    launched_goods_data['is_launched'] = 0
                    launched_goods_data['create_time'] = datetime.datetime.now()
                    launched_goods_data['is_self'] = 1
                    LaunchedGoods.objects.get_or_create(defaults=launched_goods_data, goods_id=goods.id, is_self=1)
        return queryset.order_by('-is_self', 'id')

    def create(self, request, *args, **kwargs):
        goods_id = self.request.data.get('goods_id', None)
        launchedgoods_array = self.request.data.get('launchedgoods_array', None)
        if not all([goods_id, launchedgoods_array]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(launchedgoods_array, list):
            return Response({'error': '参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                while True:
                    try:
                        goods = Goods.objects.get(id=goods_id)
                    except:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '无效商品id'}, status=status.HTTP_400_BAD_REQUEST)
                    origin_remain_stock = goods.remain_stock
                    count = 0
                    for launchedgoods in launchedgoods_array:
                        launchedgoods_data = {}
                        launchedgoods_data['level_id'] = launchedgoods['level_id']
                        launchedgoods_data['stock'] = launchedgoods['stock']
                        launchedgoods_data['goods_id'] = goods_id
                        launchedgoods_data['create_time'] = datetime.datetime.now()
                        launchedgoods_data['price'] = goods.price
                        launchedgoods_data['category_id'] = goods.category_id
                        instance, create = LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=launchedgoods_data['level_id'], goods_id=goods_id)
                        if create:
                            count += int(launchedgoods['stock'])
                    new_remain_stock = origin_remain_stock + count
                    result = Goods.objects.filter(id=instance.goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock)
                    if result == 0:
                        continue
                    break
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '上架成失败'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '上架成功'}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        stock = self.request.data.get('stock', None)
        if not stock:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            stock = int(stock)
        except:
            return Response({'error': '库存参数格式有误, 请输入整数型'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                if instance.is_self == 0:
                    while True:
                        instance = LaunchedGoods.objects.get(id=instance.id)
                        goods = Goods.objects.get(id=instance.goods_id)
                        origin_remain_stock = goods.remain_stock
                        launched_origin_stock = instance.stock
                        change_stock = launched_origin_stock - stock
                        new_remain_stock = origin_remain_stock - change_stock
                        launched_result = LaunchedGoods.objects.filter(id=instance.id, stock=launched_origin_stock).update(stock=stock)
                        result = Goods.objects.filter(id=instance.goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock)
                        if result == 0:
                            continue
                        if launched_result == 0:
                            continue
                        break
                else:
                    while True:
                        instance = LaunchedGoods.objects.get(id=instance.id)
                        goods = Goods.objects.get(id=instance.goods_id)
                        origin_remain_stock = goods.remain_stock
                        origin_stock = goods.stock
                        launched_origin_stock = instance.stock
                        change_stock = launched_origin_stock - stock
                        new_remain_stock = origin_remain_stock - change_stock
                        new_stock = origin_stock - change_stock
                        launched_result = LaunchedGoods.objects.filter(id=instance.id, stock=launched_origin_stock).update(stock=stock)
                        result = Goods.objects.filter(id=instance.goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock, stock=new_stock)
                        if result == 0:
                            continue
                        if launched_result == 0:
                            continue
                        break
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '修改成功'}, status=status.HTTP_200_OK)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        is_launched = self.request.data.get('is_launched', None)
        if not is_launched:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) not in ['0', '1']:
            return Response({'error': '参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) == '0':
            instance.is_launched = 0
            instance.save()
            return Response({'success': '下架成功'}, status=status.HTTP_200_OK)
        else:
            instance.is_launched = 1
            instance.save()
            return Response({'success': '上架成功'}, status=status.HTTP_200_OK)


class GoodsCategoryModelViewSet(ModelViewSet):

    serializer_class = GoodsCategoryModelSerializer
    queryset = GoodsCategory.objects.all()
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', )


class GoodsModelViewSet(ModelViewSet):
    '''商品'''

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', )
    filter_class = GoodsFilter

    def get_serializer_class(self):
        if self.action == 'list':
            return GoodsListModelSerializer
        else:
            return GoodsRetrieveModelSerializer

    def get_serializer_context(self):
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        return {"alidiscountcoupon_id": alidiscountcoupon_id}

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        goods_tag_activity_id = self.request.query_params.get('goods_tag_activity_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = Goods.objects.all().order_by('-id')
        elif level.level == 1:
            queryset = Goods.objects.filter(launchedgoods__level__prov_id=level.id).distinct()
        elif level.level == 2:
            queryset = Goods.objects.filter(launchedgoods__level__city_id=level.id).distinct()
        elif level.level == 3:
            queryset = Goods.objects.filter(launchedgoods__level__district_id=level.id).distinct()
        else:
            queryset = Goods.objects.filter(launchedgoods__level__branch_id=level.id).distinct()
        if alidiscountcoupon_id:
            alidiscountcoupon = AliDiscountCoupon.objects.filter(id=alidiscountcoupon_id).first()
            if alidiscountcoupon and alidiscountcoupon.goods_tag:
                queryset = queryset.filter(goods_tag=alidiscountcoupon.goods_tag)
        if goods_tag_activity_id:
            goods_tag_activity = GoodsTagActivity.objects.filter(id=goods_tag_activity_id).first()
            if goods_tag_activity:
                queryset = queryset.filter(goods_tag=goods_tag_activity.goods_tag)
            # filter_goods_id_list = AliDiscountCouponGoodsAvailable.objects.filter(alidiscountcoupon_id=alidiscountcoupon_id).values_list('goods_id', flat=True)
            # if filter_goods_id_list:
            #     queryset = queryset.exclude(id__in=list(filter_goods_id_list))
        return queryset.order_by('-id')

    def upload_image(self, request):
        user = self.request.iser
        img = self.request.FILES.get('img', None)
        merchant_id = self.request.data.get('merchant_id', None)
        if not all([img, merchant_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if img.size > 2097152:
            return Response({'error': '照片不得超过2M,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        img_str = img.read()
        img.seek(0)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户号'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            img_id = f'youhuiquanyi/{merchant.wyfMerchantID}/goods_image{"%06d" % randint(0, 999999)}.png'
            mid_img = pic_upload(img_str, key=img_id)
        except Exception as e:
            logger.error(e)
            return Response({'error': '图片上传失败,请重新上传!'}, status=status.HTTP_400_BAD_REQUEST)
        return Response({'success': '操作成功', 'img_id': f'https://circle.sutpay.cn/{img_id}'}, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        name = self.request.data.get('name', None)
        caption = self.request.data.get('caption', None)
        desc_detail = self.request.data.get('desc_detail', None)
        price = self.request.data.get('price', None)
        market_price = self.request.data.get('market_price', None)
        default_image = self.request.data.get('default_image', None)
        image_array = self.request.data.get('image_array', None)
        merchant_id = self.request.data.get('merchant_id', None)
        manufacturer = self.request.data.get('manufacturer', None)
        specifications = self.request.data.get('specifications', None)
        category_id = self.request.data.get('category_id', None)
        goods_tag = self.request.data.get('goods_tag', None)
        order_type = self.request.data.get('order_type', 1)
        is_group = self.request.data.get('is_group', None)
        group_price = self.request.data.get('group_price', None)
        group_order_num = self.request.data.get('group_order_num', None)
        group_limit_time = self.request.data.get('group_limit_time', None)
        group_limit_type = self.request.data.get('group_limit_type', None)
        proof = self.request.data.get('proof', None)
        desc_pack = self.request.data.get('desc_pack', '')
        if not all([name, caption, desc_detail, price, market_price, default_image, image_array, merchant_id, manufacturer, specifications, category_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            desc_detail = json.dumps(desc_detail)
            # image_array = json.dumps(image_array)
        except:
            return Response({'error': '商品详情数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except:
            return Response({'error': '无效商品类别参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            merchant = Merchant.objects.get(id=merchant_id)
        except:
            return Response({'error': '无效商户id'}, status=status.HTTP_400_BAD_REQUEST)
        goods_data = {}
        if str(is_group) == '1':
            if not all([group_price, group_limit_time, group_order_num, group_limit_type]):
                return Response({'error': '请上传拼团的其他信息'}, status=status.HTTP_400_BAD_REQUEST)
            if str(group_limit_type) not in ['1', '2']:
                return Response({'error': '拼团时限类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                group_price = Decimal(group_price)
                group_limit_time = int(group_limit_time)
            except:
                return Response({'error': '拼团金额时限参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            if group_price <= Decimal('0'):
                return Response({'error': '拼团金额不能小于0'}, status=status.HTTP_400_BAD_REQUEST)
            goods_data['is_group'] = is_group
            goods_data['group_price'] = group_price
            goods_data['group_order_num'] = group_order_num
            goods_data['group_limit_time'] = group_limit_time
            goods_data['group_limit_type'] = group_limit_type
        goods_data['name'] = name
        goods_data['caption'] = caption
        goods_data['desc_detail'] = desc_detail
        goods_data['desc_pack'] = desc_pack
        goods_data['price'] = price
        goods_data['market_price'] = market_price
        goods_data['default_image'] = default_image.replace('https://circle.sutpay.cn/', '')
        goods_data['merchant_id'] = merchant_id
        goods_data['manufacturer'] = manufacturer
        goods_data['specifications'] = specifications
        goods_data['is_launched'] = 1
        goods_data['category_id'] = category_id
        goods_data['goods_tag'] = goods_tag
        goods_data['order_type'] = order_type
        goods_data['longitude'] = merchant.longitude
        goods_data['latitude'] = merchant.latitude
        goods_data['order_species'] = 2
        goods_data['proof'] = proof.replace('https://circle.sutpay.cn/', '')
        area = GoodsAreaCode.objects.filter(district_name=merchant.district_name, prov_name=merchant.prov_name, city_name=merchant.city_name).first()
        if area:
            goods_data['area_id'] = area.id
        try:
            goods = Goods.objects.create(**goods_data)
            for image in image_array:
                GoodsImage.objects.create(
                    goods_id=goods.id,
                    image = image.replace('https://circle.sutpay.cn/', '')
                )
            try:
                GoodsAuditRecord.objects.create(
                    goods_id=goods.id,
                    create_user_id=user.id,
                    audit_type=1,
                    remark="新增商品"
                )
            except:
                pass
            return Response({'success': '创建成功', 'goods_id': goods.id}, status=status.HTTP_200_OK)
        except Exception as e:
            logger.error(str(e))
            return Response({'error': '创建失败.请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        name = self.request.data.get('name', None)
        caption = self.request.data.get('caption', None)
        desc_detail = self.request.data.get('desc_detail', None)
        desc_pack = self.request.data.get('desc_pack', '')
        price = self.request.data.get('price', None)
        market_price = self.request.data.get('market_price', None)
        default_image = self.request.data.get('default_image', None)
        image_array = self.request.data.get('image_array', None)
        manufacturer = self.request.data.get('manufacturer', None)
        specifications = self.request.data.get('specifications', None)
        goods_tag = self.request.data.get('goods_tag', None)
        order_type = self.request.data.get('order_type', None)
        is_group = self.request.data.get('is_group', None)
        group_price = self.request.data.get('group_price', None)
        group_order_num = self.request.data.get('group_order_num', None)
        group_limit_time = self.request.data.get('group_limit_time', None)
        group_limit_type = self.request.data.get('group_limit_type', None)
        proof = self.request.data.get('proof', None)
        if not all([name, caption, desc_detail, price, market_price, default_image, image_array, manufacturer, specifications, proof]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            desc_detail = json.dumps(desc_detail)
            # image_array = json.dumps(image_array)
        except:
            return Response({'error': '商品详情数据格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_group) == '1':
            if not all([group_price, group_limit_time, group_order_num, group_limit_type]):
                return Response({'error': '请上传拼团的其他信息'}, status=status.HTTP_400_BAD_REQUEST)
            if str(group_limit_type) not in ['1', '2']:
                return Response({'error': '拼团时限类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                group_price = Decimal(group_price)
                group_limit_time = int(group_limit_time)
            except:
                return Response({'error': '拼团金额时限参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            if group_price <= Decimal('0'):
                return Response({'error': '拼团金额不能小于0'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance.name = name
            instance.caption = caption
            instance.desc_detail = desc_detail
            instance.desc_pack = desc_pack
            instance.price = price
            instance.goods_tag = goods_tag
            instance.market_price = market_price
            instance.default_image = default_image.replace('https://circle.sutpay.cn/', '')
            instance.manufacturer = manufacturer
            instance.specifications = specifications
            instance.is_group = is_group
            instance.group_price = group_price
            instance.group_limit_time = group_limit_time
            instance.group_order_num = group_order_num
            instance.group_limit_type = group_limit_type
            instance.group_limit_type = group_limit_type
            instance.proof = proof.replace('https://circle.sutpay.cn/', '')
            if str(order_type) in ['1', '5', '6']:
                instance.order_type = order_type
            instance.save()
            GoodsImage.objects.filter(goods_id=instance.id).delete()
            for image in image_array:
                GoodsImage.objects.create(
                    goods_id=instance.id,
                    image = image.replace('https://circle.sutpay.cn/', '')
                )
            return Response({'success': '编辑商品成功'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '编辑商品失败'}, status=status.HTTP_400_BAD_REQUEST)

    def applyment(self, request):
        user = self.request.iser
        applyment_id = self.request.data.get('applyment_id')
        reject_reason = self.request.data.get('reject_reason', None)
        applyment_status = self.request.data.get('applyment_status', None)
        if not applyment_id:
            return Response({'error': '缺少申请单参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(applyment_status) not in ['1', '2']:
            return Response({'error': '审核状态参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            applyment = GoodsModifyApplyment.objects.get(id=applyment_id)
        except:
            return Response({'error': '无效申请单id'}, status=status.HTTP_400_BAD_REQUEST)
        if applyment.applyment_status != 1:
            return Response({'error': '申请单状态有误,请勿重复操作'}, status=status.HTTP_400_BAD_REQUEST)
        goods = applyment.goods
        launched_goods = LaunchedGoods.objects.filter(goods_id=goods.id, level_id=applyment.level_id).first()
        if str(applyment_status) == '2':
            if not reject_reason:
                return Response({'error': '请输入驳回原因'}, status=status.HTTP_400_BAD_REQUEST)
            if applyment.applyment_type == 1:
                applyment.applyment_status = 3
                applyment.reject_reason = reject_reason
                applyment.save()
                goods.is_launched = 3
                if applyment.update_word:
                    update_word = json.loads(applyment.update_word)
                    for word in update_word:
                        if word == 'name':
                            goods.name = applyment.name
                        elif word == 'desc_detail':
                            goods.desc_detail = applyment.desc_detail
                        elif word == 'price':
                            goods.price = applyment.price
                        elif word == 'default_image':
                            default_image = applyment.default_image.__str__()
                            goods.default_image = default_image.replace('https://circle.sutpay.cn', '')
                        elif word == 'manufacturer':
                            goods.manufacturer = applyment.manufacturer
                        elif word == 'specifications':
                            goods.specifications = applyment.specifications
                        elif word == 'market_price':
                            goods.market_price = applyment.market_price
                        elif word == 'caption':
                            goods.caption = applyment.caption
                        elif word == 'goodsimage_set':
                            goodsimage_set = goods.goodsimage_set.all().delete()
                            image_array = json.loads(applyment.image_array)
                            for image in image_array:
                                GoodsImage.objects.create(
                                    goods_id=goods.id,
                                    image=image.replace('https://circle.sutpay.cn/', '')
                                )
                goods.save()
            else:
                applyment.applyment_status = 3
                applyment.reject_reason = reject_reason
                applyment.save()
                goods.is_launched = 3
                goods.save()
            remark = '超级管理员审核商品(驳回)'
        elif str(applyment_status) == '1':
            if applyment.applyment_type == 1:
                applyment.applyment_status = 2
                applyment.save()
                goods.remain_stock = goods.remain_stock + launched_goods.stock - applyment.stock
                goods.is_launched = 1
                goods.save()
            else:
                applyment.applyment_status = 2
                applyment.save()
                goods.remain_stock = goods.remain_stock + launched_goods.stock - applyment.stock
                goods.is_launched = 1
                goods.save()
                merchantenter_set = goods.merchant.merchantenter_set.all()
                for merchantenter in merchantenter_set:
                    launchedgoods_data = {}
                    launchedgoods_data['level_id'] = merchantenter.level_id
                    launchedgoods_data['goods_id'] = goods.id
                    launchedgoods_data['is_launched'] = 0
                    launchedgoods_data['name'] = goods.name
                    launchedgoods_data['category_id'] = 1
                    launchedgoods_data['stock'] = 0
                    LaunchedGoods.objects.get_or_create(defaults=launchedgoods_data, level_id=merchantenter.level_id, goods_id=goods.id)
            remark = '超级管理员审核商品(通过)'
        else:
            return Response({'error': '审核状态参数有误'}, status=status.HTTP_200_OK)
        try:
            GoodsAuditRecord.objects.create(
                goods_id=goods.id,
                create_user_id=user.id,
                audit_type=2,
                remark=remark
            )
        except:
            pass
        try:
            expedite_applyment_send.delay({'id': applyment.id})
        except:
            pass
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.is_launched not in [0, 1]:
            return Response({'error': '商品状态有误,无法操作'}, status=status.HTTP_400_BAD_REQUEST)
        is_launched = self.request.data.get('is_launched', None)
        if not is_launched:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) not in ['0', '1']:
            return Response({'error': '参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(is_launched) == '0':
            instance.is_launched = 0
            instance.save()
            return Response({'success': '下架成功'}, status=status.HTTP_200_OK)
        else:
            instance.is_launched = 1
            instance.save()
            return Response({'success': '上架成功'}, status=status.HTTP_200_OK)

    def export_goods(self, request):
        user = self.request.iser
        is_launched = self.request.query_params.get('is_launched', None)
        search = self.request.query_params.get('search', None)
        level = user.level
        if level.level == 0:
            condition = 'WHERE level_id IN (SELECT id FROM tb_u_level)'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        # if search:
        #     condition = condition + f' AND mobile LIKE "%{search}%"'
        if is_launched:
            condition = condition + f' AND is_launched in ({is_launched})'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT e.*,f.category_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.merchant_name,short_name,wyfMerchantID,level_id FROM (SELECT id,equityID,name,category_id,is_launched,merchant_id,price,market_price,sales,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S')  AS create_time FROM tb_goods)AS a LEFT JOIN (SELECT id,name AS merchant_name,short_name,wyfMerchantID,level_id FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id, name AS category_name FROM tb_goods_category)AS f ON e.category_id=f.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT e.*,f.category_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.merchant_name,short_name,wyfMerchantID,level_id FROM (SELECT id,equityID,name,category_id,is_launched,merchant_id,price,market_price,sales,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S')  AS create_time FROM tb_goods)AS a LEFT JOIN (SELECT id,name AS merchant_name,short_name,wyfMerchantID,level_id FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id, name AS category_name FROM tb_goods_category)AS f ON e.category_id=f.id;
            '''
            cursor.execute(sql)
        ziduan = ['商品ID', '权益ID', '商品名称', '商品分类', '商品状态', '所属商户全称', '所属商户简称', '微邮付商户号',
                  '归属市公司', '归属区县', '归属网点', '原价', '结算价格', '销量', '上架时间']
        cols = ['id', 'equityID', 'name', 'category_name', 'is_launched', 'merchant_name', 'short_name', 'wyfMerchantID',
                'city_name', 'district_name', 'branch_name', 'market_price', 'price', 'sales', 'create_time']
        response = StreamingHttpResponse(self.get_goods_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('商品信息.csv'))
        return response

    def get_goods_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        STATUS_ENUM = {
            0: '已下架',
            1: '已上架',
            2: '审核中',
            3: '已驳回'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'is_launched':
                    tmp_str += '"%s",' % (STATUS_ENUM[row[col]])
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def pinned(self, request):
        goods_id = self.request.data.get('goods_id', None)
        if not goods_id:
            return Response({'error': '请上传商品id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=goods_id)
        except:
            return Response({'error': '无效商品id'}, status=status.HTTP_200_OK)
        max_sort = Goods.objects.aggregate(Max("sort"))["sort__max"]
        instance.sort = max_sort+1
        instance.save()
        return Response({'success': '置顶成功'}, status=status.HTTP_200_OK)

    def batch_update_goods_stock(self, reqeust):
        update_type = self.request.data.get('update_type', '1')
        goods_id = self.request.data.get('goods_id', None)
        stock = self.request.data.get('stock', None)
        if not str(stock):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            goods = self.get_queryset().get(id=goods_id)
        except:
            return Response({'error': '无效商品id'}, status=status.HTTP_400_BAD_REQUEST)
        stock = int(stock)
        if str(update_type) == '1':
            if int(stock) < 0:
                return Response({'error': '调整库存不得小于0'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            if int(stock) <= 0:
                return Response({'error': '增加库存须大于0'}, status=status.HTTP_400_BAD_REQUEST)
        launchedgoods_set = LaunchedGoods.objects.filter(goods_id=goods_id)
        for launchedgoods in launchedgoods_set:
            launchedgoods_id = launchedgoods.id
            while True:
                launchedgoods = LaunchedGoods.objects.get(id=launchedgoods_id)
                launched_origin_stock = launchedgoods.stock
                if str(update_type) == '1':
                    change_stock = launched_origin_stock - stock
                else:
                    change_stock = -stock
                new_stock = launched_origin_stock - change_stock
                launched_result = LaunchedGoods.objects.filter(id=launchedgoods_id, stock=launched_origin_stock).update(stock=new_stock)
                if launched_result == 0:
                    continue
                break
            while True:
                goods = Goods.objects.get(id=goods_id)
                origin_remain_stock = goods.remain_stock
                origin_stock = goods.stock
                new_remain_stock = origin_remain_stock - change_stock
                new_stock = origin_stock - change_stock
                result = Goods.objects.filter(id=goods_id, remain_stock=origin_remain_stock).update(remain_stock=new_remain_stock, stock=new_stock)
                if result == 0:
                    continue
                break
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def batch_unbind_goods_tag(self, request):
        goods_id_array = self.request.data.get('goods_id_array', None)
        if not goods_id_array:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        Goods.objects.filter(id__in=goods_id_array).update(goods_tag=None)
        return Response({'success': '解绑成功'}, status=status.HTTP_200_OK)


class AliDiscountCouponInfoModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_class = AliDiscountCouponInfoFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('mobile', 'login_id')

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level_id', None)
        alidiscountcoupon_level_id = self.request.query_params.get('alidiscountcoupon_level_id', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        if alidiscountcoupon_level_id:
            try:
                couponlevel = AliDiscountCouponLevel.objects.get(id=alidiscountcoupon_level_id)
                self.request.data['acitivty_info'] = AliDiscountCouponLevelListModelSerializer(couponlevel).data
            except:
                self.request.data['acitivty_info'] = {}
        if level.level == 0:
            queryset = AliDiscountCouponInfo.objects.all()
        elif level.level == 1:
            queryset = AliDiscountCouponInfo.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = AliDiscountCouponInfo.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = AliDiscountCouponInfo.objects.filter(level__district_id=level.id)
        else:
            queryset = AliDiscountCouponInfo.objects.filter(level__branch_id=level.id)
        return queryset.order_by('-id')

    def get_serializer_class(self):
        if self.action == 'list':
            return AliDiscountCouponInfoListModelSerializer
        else:
            return AliDiscountCouponInfoRetrieveModelSerializer

    def export_discountinfo(self, request):
        user = self.request.iser
        activity_id = self.request.query_params.get('activity_id', None)
        alidiscountcoupon_level_id = self.request.query_params.get('alidiscountcoupon_level_id', None)
        level_id = self.request.query_params.get('level_id', None)
        status = self.request.query_params.get('status', None)
        search = self.request.query_params.get('search', None)
        level = user.level
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE id != 0'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        if search:
            condition = condition + f' AND mobile LIKE "%{search}%"'
        if activity_id:
            condition = condition + f' AND alidiscountcoupon_id in ({activity_id})'
        if status:
            condition = condition + f' AND status in ({status})'
        if alidiscountcoupon_level_id:
            condition = condition + f' AND alidiscountcoupon_level_id={alidiscountcoupon_level_id}'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            # sql = f'''
            # SELECT r.*,s.goods_name FROM (SELECT m.*,n.coupons_id FROM (SELECT k.*,l.orderNum,total_count,total_price,realpay_amount,create_time,order_id FROM (SELECT i.*,j.trade_no FROM (SELECT g.*,h.activity_name FROM (SELECT e.*,f.account,name FROM (SELECT c.*,d.nickname FROM (SELECT a.*,b.idcode,realname FROM (SELECT id,mobile,status,customer_user_id,companyuser_id,level_id,DATE_FORMAT(gmt_distributed,'%Y-%m-%d %H:%i:%S')AS gmt_distributed,DATE_FORMAT(gmt_undo,'%Y-%m-%d %H:%i:%S')AS gmt_undo,alidiscountcoupon_id FROM tb_ali_discount_coupon_info {condition})AS a LEFT JOIN (SELECT id,realname,idcode FROM tb_u_customer_user)AS b ON a.customer_user_id=b.id)AS c LEFT JOIN (SELECT id,nickname FROM tb_u_user)AS d ON c.companyuser_id=d.id)AS e LEFT JOIN (SELECT id,name,account FROM tb_u_level)AS f ON e.level_id=f.id)AS g LEFT JOIN (SELECT id,activity_name FROM tb_ali_discount_coupon)AS h on g.alidiscountcoupon_id=h.id)AS i LEFT JOIN (SELECT trade_no,voucherinfo_id FROM tb_ali_discount_coupon_bill_details)AS j ON i.id=j.voucherinfo_id)AS k LEFT JOIN (SELECT orderNum,total_count,total_price,create_time,realpay_amount,id AS order_id FROM tb_order_info)AS l ON k.trade_no=l.orderNum)AS m LEFT JOIN (SELECT GROUP_CONCAT(coupons_id)AS coupons_id,order_id FROM tb_goods_coupons GROUP BY order_id)AS n ON m.order_id=n.order_id)AS r LEFT JOIN (SELECT GROUP_CONCAT(q.name)AS goods_name,q.order_id FROM (SELECT o.*,p.name FROM (SELECT order_id,goods_id FROM tb_order_goods)AS o LEFT JOIN (SELECT id,name FROM tb_goods)AS p ON o.goods_id=p.id)AS q GROUP BY q.order_id)AS s ON r.order_id=s.order_id;
            # '''
            sql = f'''
            SELECT m.*,n.vice_idcode,vice_realname FROM (SELECT k.*,l.orderNum,total_count,total_price,realpay_amount,create_time,order_id FROM (SELECT i.*,j.trade_no FROM (SELECT g.*,h.activity_name,coupon_way,coupon_channel FROM (SELECT e.*,f.account,name FROM (SELECT c.*,d.nickname FROM (SELECT a.*,b.idcode,realname FROM (SELECT id,mobile,status,customer_user_id,companyuser_id,level_id,DATE_FORMAT(gmt_distributed,'%Y-%m-%d %H:%i:%S')AS gmt_distributed,DATE_FORMAT(gmt_undo,'%Y-%m-%d %H:%i:%S')AS gmt_undo,alidiscountcoupon_id,customeruservice_id,out_biz_no,user_id,out_biz_order,voucher_id,login_id FROM tb_ali_discount_coupon_info {condition})AS a LEFT JOIN (SELECT id,realname,idcode FROM tb_u_customer_user)AS b ON a.customer_user_id=b.id)AS c LEFT JOIN (SELECT id,nickname FROM tb_u_user)AS d ON c.companyuser_id=d.id)AS e LEFT JOIN (SELECT id,name,account FROM tb_u_level)AS f ON e.level_id=f.id)AS g LEFT JOIN (SELECT id,activity_name,coupon_way,coupon_channel FROM tb_ali_discount_coupon)AS h on g.alidiscountcoupon_id=h.id)AS i LEFT JOIN (SELECT trade_no,voucherinfo_id FROM tb_ali_discount_coupon_bill_details)AS j ON i.id=j.voucherinfo_id)AS k LEFT JOIN (SELECT orderNum,total_count,total_price,create_time,realpay_amount,id AS order_id FROM tb_order_info WHERE order_species=2)AS l ON k.trade_no=l.orderNum)AS m LEFT JOIN (SELECT id,realname AS vice_realname,idcode AS vice_idcode FROM tb_u_customer_user_vice)AS n ON m.customeruservice_id=n.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT r.*,s.goods_name FROM (SELECT m.*,n.coupons_id FROM (SELECT k.*,l.orderNum,total_count,total_price,realpay_amount,create_time,order_id FROM (SELECT i.*,j.trade_no FROM (SELECT g.*,h.activity_name FROM (SELECT e.*,f.account,name FROM (SELECT c.*,d.nickname FROM (SELECT a.*,b.idcode,realname FROM (SELECT id,mobile,status,customer_user_id,companyuser_id,level_id,DATE_FORMAT(gmt_distributed,'%Y-%m-%d %H:%i:%S')AS gmt_distributed,DATE_FORMAT(gmt_undo,'%Y-%m-%d %H:%i:%S')AS gmt_undo,alidiscountcoupon_id FROM tb_ali_discount_coupon_info)AS a LEFT JOIN (SELECT id,realname,idcode FROM tb_u_customer_user)AS b ON a.customer_user_id=b.id)AS c LEFT JOIN (SELECT id,nickname FROM tb_u_user)AS d ON c.companyuser_id=d.id)AS e LEFT JOIN (SELECT id,name,account FROM tb_u_level)AS f ON e.level_id=f.id)AS g LEFT JOIN (SELECT id,activity_name FROM tb_ali_discount_coupon)AS h on g.alidiscountcoupon_id=h.id)AS i LEFT JOIN (SELECT trade_no,voucherinfo_id FROM tb_ali_discount_coupon_bill_details)AS j ON i.id=j.voucherinfo_id)AS k LEFT JOIN (SELECT orderNum,total_count,total_price,create_time,realpay_amount,id AS order_id FROM tb_order_info)AS l ON k.trade_no=l.orderNum)AS m LEFT JOIN (SELECT GROUP_CONCAT(coupons_id)AS coupons_id,order_id FROM tb_goods_coupons GROUP BY order_id)AS n ON m.order_id=n.order_id)AS r LEFT JOIN (SELECT GROUP_CONCAT(q.name)AS goods_name,q.order_id FROM (SELECT o.*,p.name FROM (SELECT order_id,goods_id FROM tb_order_goods)AS o LEFT JOIN (SELECT id,name FROM tb_goods)AS p ON o.goods_id=p.id)AS q GROUP BY q.order_id)AS s ON r.order_id=s.order_id;
            '''
            cursor.execute(sql)
        ziduan = ['id', '优惠券ID', '领取手机号', '领取状态', '领取人姓名', '领取人证件号码', '派发人姓名', '派发人所属网点', '网点机构号',
                  '派发时间', '撤销时间', '活动名称', '数量', '订单金额', '实际支付金额', '下单时间', '订单号', '派发单号', 'openid', '三方订单号']
        cols = ['id', 'voucher_id', 'mobile', 'status', 'realname', 'idcode', 'nickname', 'name', 'account', 'gmt_distributed', 'gmt_undo', 'activity_name',
                'total_count', 'total_price', 'realpay_amount', 'create_time', 'trade_no', 'out_biz_no', 'user_id', 'out_biz_order']
        response = StreamingHttpResponse(self.get_discountinfo_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('优惠券派发核销数据.csv'))
        return response

    def get_discountinfo_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        STATUS_ENUM = {
            0: '待领取',
            1: '待核销',
            2: '不可用',
            3: '删除状态',
            4: '发送中',
            5: '已转增',
            6: '未领取',
            7: '已核销',
            8: '使用中',
            9: '已退款',
            10: '退款中',
            11: '未激活',
            12: '已过期',
            13: '已撤销',
            14: '领取失败'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'status':
                    tmp_str += '"%s",' % (STATUS_ENUM[row[col]])
                elif col in ['realname']:
                    if row['customeruservice_id']:
                        tmp_str += '"%s",' % (str(row['vice_realname']).encode('GBK', 'ignore').decode('gbk') if row['vice_realname'] else '')
                    else:
                        tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col in ['idcode']:
                    if row['customeruservice_id']:
                        tmp_str += '"\'%s",' % (str(row['vice_idcode']).encode('GBK', 'ignore').decode('gbk') if row['vice_idcode'] else '')
                    else:
                        tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col == 'mobile':
                    if row['coupon_way'] == 5 and row['coupon_channel'] == 1:
                        tmp_str += '"%s",' % (str(row['login_id']).encode('GBK', 'ignore').decode('gbk') if row['login_id'] else '')
                    else:
                        tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col in ['trade_no', 'coupons_id', 'out_biz_no', 'out_biz_order']:
                    tmp_str += '"\'%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.status in [1, 8, 9]:
            alidiscountcoupon = instance.alidiscountcoupon
            if alidiscountcoupon.coupon_channel == 1:
                alipayopen = C_AlipayOpen()
                result = json.loads(alipayopen.voucherquery(instance.voucher_id))
                if result['status'] == 'USED':
                    alidiscountcoupon.use_count += 1
                    alidiscountcoupon.save()
                    try:
                        if 'bill_details' in result:
                            for bill_datail in result['bill_details']:
                                instance.gmt_use = bill_datail['gmt_create']
                                bill_datail['voucherinfo_id'] = instance.id
                                AliDiscountCouponBillDetails.objects.create(**bill_datail)
                    except:
                        pass
                    try:
                        alidiscountcoupon_level = instance.alidiscountcoupon_level
                        alidiscountcoupon_level.use_number += 1
                        alidiscountcoupon_level.p_use_number += 1
                        alidiscountcoupon_level.save()
                        relation_set = alidiscountcoupon_level.child_set.all()
                        for relation in relation_set:
                            parent = relation.parent
                            parent.p_use_number += 1
                            parent.save()
                    except:
                        pass
                instance.status = instance.STATUS_ENUM[result['status']]
                instance.save()
            elif alidiscountcoupon.coupon_channel == 2:
                coupon_id = instance.voucher_id
                openid = instance.user_id
                appid = instance.appid
                if alidiscountcoupon.platform_id == 13:
                    distribute_channel = Channel.objects.get(id=13)
                else:
                    distribute_channel = Channel.objects.get(id=9)
                result = favor_query_coupons_sichun(coupon_id, openid, appid, distribute_channel)
                try:
                    if result['status'] == 'USED':
                        alidiscountcoupon.use_count += 1
                        alidiscountcoupon.save()
                        try:
                            if 'bill_details' in result:
                                for bill_datail in result['bill_details']:
                                    instance.gmt_use = bill_datail['gmt_create']
                                    bill_datail['voucherinfo_id'] = instance.id
                                    AliDiscountCouponBillDetails.objects.create(**bill_datail)
                        except:
                            pass
                        try:
                            alidiscountcoupon_level = instance.alidiscountcoupon_level
                            alidiscountcoupon_level.use_number += 1
                            alidiscountcoupon_level.p_use_number += 1
                            alidiscountcoupon_level.save()
                            relation_set = alidiscountcoupon_level.child_set.all()
                            for relation in relation_set:
                                parent = relation.parent
                                parent.p_use_number += 1
                                parent.save()
                        except:
                            pass
                        instance.status = 7
                        instance.gmt_use = datetime.datetime.now()
                    elif result['status'] == 'EXPIRED':
                        instance.status = 12
                    instance.save()
                except:
                    pass
        serializer = self.get_serializer(instance)
        return Response(serializer.data)


class AliDiscountCouponModelViewSet(ModelViewSet):

    pagination_class = MyPage
    search_fields = ('activity_name', 'template_id', 'product_no')
    filter_class = AliDiscountCouponFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        customizeactivity_id = self.request.query_params.get('customizeactivity_id', None)
        goods_tag_activity_id = self.request.query_params.get('goods_tag_activity_id', None)
        if self.action == 'list':
            level_id = self.request.query_params.get('level_id', None)
            if level_id:
                try:
                    level_list = get_level_list(level)
                    level_id = int(level_id)
                    if level_id in level_list:
                        level = Level.objects.filter(id=level_id).first()
                except:
                    pass
        if level.level == 0:
            queryset = AliDiscountCoupon.objects.all().order_by('-id')
        elif level.level == 1:
            queryset = AliDiscountCoupon.objects.filter(level__prov_id=level.id).order_by('-id')
        elif level.level == 2:
            queryset = AliDiscountCoupon.objects.filter(level__city_id=level.id).order_by('-id')
        elif level.level == 3:
            queryset = AliDiscountCoupon.objects.filter(level__district_id=level.id).order_by('-id')
        else:
            queryset = AliDiscountCoupon.objects.filter(level__branch_id=level.id).order_by('-id')
        if customizeactivity_id:
            try:
                customizeactivity = CustomizeActivity.objects.get(id=customizeactivity_id)
                if customizeactivity.activity_type == 1:
                    queryset = queryset.exclude(customizeactivityrules__customizeactivity_id=customizeactivity_id)
            except:
                pass
        if goods_tag_activity_id:
            goods_tag_activity = GoodsTagActivity.objects.filter(id=goods_tag_activity_id).first()
            if goods_tag_activity:
                today = datetime.datetime.now()
                queryset = queryset.filter(goods_tag=goods_tag_activity.goods_tag, publish_end_time__gte=today)
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return AliDiscountCouponListModelSerializer
        else:
            return AliDiscountCouponRetrieveModelSerializer

    def check_template(self, request):
        user = self.request.iser
        coupon_channel = self.request.data.get('coupon_channel', None)
        platform_id = self.request.data.get('platform_id', None)
        template_id = self.request.data.get('template_id', None)
        if not coupon_channel:
            return Response({'error': '优惠券类型必传'}, status=status.HTTP_400_BAD_REQUEST)
        if str(coupon_channel) == '1':
            if not template_id:
                return Response({'error': '支付宝活动请传模板id'}, status=status.HTTP_400_BAD_REQUEST)
            # activity = AliDiscountCoupon.objects.filter(template_id=template_id)
            # if activity:
            #     return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=2).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_alidiscountcoupon(template_id, platform)
            if not data_dict['success']:
                return Response({'error': data_dict['errorMsg']}, status=status.HTTP_400_BAD_REQUEST)
            try:
                data = {}
                data['template_name'] = data_dict['data']['dataVO']['form']['activityName']
                transaction_minimum = Decimal(data_dict['data']['dataVO']['form']['overAmount'])
                coupon_amount = Decimal(data_dict['data']['dataVO']['form']['overReduceAmount'])
                data['floor_amount'] = f"{transaction_minimum}"
                data['transaction_minimum'] = f"{coupon_amount}"
                available_begin_time = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['sendStartTime']/1000)
                available_end_time = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['sendEndTime']/1000)
                data['publish_start_time'] = f"{available_begin_time.strftime('%Y-%m-%d')}"
                data['publish_end_time'] = f"{available_end_time.strftime('%Y-%m-%d')}"
                data['max_number'] = int(Decimal(data_dict['data']['dataVO']['form']['budgetAmt'])/Decimal(data_dict['data']['dataVO']['form']['overReduceAmount']))
                return Response({'success': '检验成功', 'data': data}, status=status.HTTP_200_OK)
            except:
                return Response({'error': '校验失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(coupon_channel) == '2':
            if not template_id:
                return Response({'error': '微信活动请传批次号id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=1).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            # activity = AliDiscountCoupon.objects.filter(template_id=template_id)
            # if activity:
            #     return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_stockinfo(template_id, platform)
            if 'code' in data_dict:
                return Response({'error': data_dict['message']}, status=status.HTTP_400_BAD_REQUEST)
            if data_dict['stock_type'] != 'NORMAL':
                return Response({'error': '暂支持代金券批次活动'}, status=status.HTTP_400_BAD_REQUEST)
            if data_dict['stock_use_rule']['coupon_type'] != 'NORMAL':
                return Response({'error': '暂不支持减至券批次活动'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                data = {}
                data['template_name'] = data_dict['stock_name']
                transaction_minimum = (Decimal(data_dict['stock_use_rule']['fixed_normal_coupon']['transaction_minimum']) / Decimal('100')).quantize(Decimal('0.00'))
                coupon_amount = (Decimal(data_dict['stock_use_rule']['fixed_normal_coupon']['coupon_amount']) / Decimal('100')).quantize(Decimal('0.00'))
                data['floor_amount'] = f"{transaction_minimum}"
                data['transaction_minimum'] = f"{coupon_amount}"
                available_begin_time = datetime.datetime.strptime(data_dict['available_begin_time'].replace('+08:00', ''), '%Y-%m-%dT%H:%M:%S')
                available_end_time = datetime.datetime.strptime(data_dict['available_end_time'].replace('+08:00', ''), '%Y-%m-%dT%H:%M:%S')
                data['publish_start_time'] = f"{available_begin_time.strftime('%Y-%m-%d')}"
                data['publish_end_time'] = f"{available_end_time.strftime('%Y-%m-%d')}"
                data['max_number'] = data_dict['stock_use_rule']['max_coupons']
                return Response({'success': '检验成功', 'data': data}, status=status.HTTP_200_OK)
            except:
                return Response({'error': '校验失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(coupon_channel) == '5':
            if not template_id:
                return Response({'error': '美团活动请传批次号id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=5).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_meituan_acitivty(template_id, platform)
            if data_dict['status'] == 'fail':
                return Response({'error': data_dict['errorMsg']}, status=status.HTTP_400_BAD_REQUEST)
            if not data_dict['data']:
                return Response({'error': '无效批次号'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                data = {}
                data['template_name'] = data_dict['data']['titleShow']
                transaction_minimum = data_dict['data']['discountDetaiDtos'][0]['quotaValue']
                coupon_amount = data_dict['data']['discountDetaiDtos'][0]['reduceValue']
                data['floor_amount'] = f"{transaction_minimum}"
                data['transaction_minimum'] = f"{coupon_amount}"
                available_begin_time = datetime.datetime.strptime(data_dict['data']['validBeginTime'], "%Y-%m-%d %H:%M:%S")
                available_end_time = datetime.datetime.strptime(data_dict['data']['assignEndTime'], "%Y-%m-%d %H:%M:%S")
                data['publish_start_time'] = f"{available_begin_time.strftime('%Y-%m-%d')}"
                data['publish_end_time'] = f"{available_end_time.strftime('%Y-%m-%d')}"
                data['max_number'] = data_dict['data']['totalCount']
                return Response({'success': '检验成功', 'data': data}, status=status.HTTP_200_OK)
            except:
                return Response({'error': '校验失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'error': '无效活动类型参数'}, status=status.HTTP_400_BAD_REQUEST)

    def create(self, request, *args, **kwargs):
        user = self.request.iser
        coupon_channel = self.request.data.get('coupon_channel', None)
        coupon_way = self.request.data.get('coupon_way', None)
        platform_id = self.request.data.get('platform_id', None)
        template_id = self.request.data.get('template_id', None)
        level_id = self.request.data.get('level_id', None)
        name = self.request.data.get('name', '')
        fn_order_id = self.request.data.get('fn_order_id', '')
        distribution_platform_id = self.request.data.get('distribution_platform_id', None)

        transaction_minimum = self.request.data.get('transaction_minimum', None)
        publish_start_time = self.request.data.get('publish_start_time', None)
        publish_end_time = self.request.data.get('publish_end_time', None)
        max_number = self.request.data.get('max_number', None)
        max_number_by_day = self.request.data.get('max_number_by_day', '0')
        max_number_by_user = self.request.data.get('max_number_by_user', '0')
        max_number_by_day_count = self.request.data.get('max_number_by_day_count', None)
        max_number_by_user_count = self.request.data.get('max_number_by_user_count', None)
        join_limit_by_bay = self.request.data.get('join_limit_by_bay', None)
        join_limit_by_bay_count = self.request.data.get('join_limit_by_bay_count', None)
        coupon_type = self.request.data.get('coupon_type', None)
        amount = self.request.data.get('amount', None)
        is_need_auth = self.request.data.get('is_need_auth', None)
        activity_description = self.request.data.get('activity_description', None)
        usetime_type = self.request.data.get('usetime_type', None)
        start_fixed_time = self.request.data.get('start_fixed_time', None)
        end_fixed_time = self.request.data.get('end_fixed_time', None)
        invalid_day = self.request.data.get('invalid_day', None)
        if not coupon_channel:
            return Response({'error': '优惠券类型必传'}, status=status.HTTP_400_BAD_REQUEST)
        if not coupon_way:
            return Response({'error': '优惠券派发方式必传'}, status=status.HTTP_400_BAD_REQUEST)
        if not level_id:
            return Response({'error': '活动归属层级必传'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            level = Level.objects.get(id=level_id)
        except:
            return Response({'error': '无效层级参数'}, status=status.HTTP_400_BAD_REQUEST)
        if str(coupon_way) not in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']:
            return Response({'error': '优惠券派发方式参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        if str(coupon_channel) == '1':
            if not template_id:
                return Response({'error': '支付宝活动请传模板id'}, status=status.HTTP_400_BAD_REQUEST)
            activity = AliDiscountCoupon.objects.filter(template_id=template_id)
            if activity:
                return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=2).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_alidiscountcoupon(template_id, platform)
            if not data_dict['success']:
                return Response({'error': data_dict['errorMsg']}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()

                # 暴力回滚
                try:
                    alidiscountcoupon_data = {}
                    if str(coupon_way) == '3':
                        alidiscountcoupon_data['start_enable_time'] = '1970-01-01 09:00:00'
                    alidiscountcoupon_data['user_id'] = user.id
                    alidiscountcoupon_data['level_id'] = level.id
                    alidiscountcoupon_data['template_id'] = template_id
                    alidiscountcoupon_data['activity_name'] = name
                    alidiscountcoupon_data['distribution_platform_id'] = distribution_platform_id
                    alidiscountcoupon_data['name'] = data_dict['data']['dataVO']['form']['activityName']
                    transaction_minimum = Decimal(data_dict['data']['dataVO']['form']['overAmount'])
                    coupon_amount = Decimal(data_dict['data']['dataVO']['form']['overReduceAmount'])
                    alidiscountcoupon_data['floor_amount'] = f"满{transaction_minimum}元减{coupon_amount}元"
                    alidiscountcoupon_data['brand_name'] = "中国邮政储蓄银行"
                    available_begin_time = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['sendStartTime']/1000)
                    available_end_time = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['sendEndTime']/1000)
                    alidiscountcoupon_data['activity_valid_period'] = f"到{available_end_time.strftime('%Y年%m月%d日')}"
                    description = f'''1、红包有效期{available_begin_time.strftime('%Y.%m.%d %H:%M:%S')}-{available_end_time.strftime('%Y.%m.%d %H:%M:%S')}（请在红包详情页面关注红包具体有效期信息），红包不可拆分，不得提现、无法转赠、不得为他人付款，过期自动作废，无法使用，同时也不予补发。
        2、该红包适用于指定间连商家及门店，使用支付宝选择中国邮政储蓄银行借记卡且单笔实际支付金额大于{transaction_minimum}元时可抵扣使用（实际使用范围以红包可抵扣为准）。使用红包的订单若发生退款，订单可退金额及红包可退面额以消费者的退款页面信息为准。退回的红包若在有效期内则可继续使用，且使用规则不变；退回的红包若已过有效期则无法使用，且不予补发。
        3、支付宝端的中国邮政储蓄银行活动，仅限中华人民共和国境内的支付宝实名认证用户参与；同一用户活动期内仅能参加{data_dict['data']['dataVO']['form']['totalCountLimit']}次活动。同一支付宝账号、手机号、身份证、手机终端，符合以上任一条件均视为同一用户。
        4、为确保活动公平性，如用户出现不正当行为（如虚假交易、作弊、恶意套取现金、刷信等），银行有权撤销用户优惠资格，并有权收回用户获得的福利。
        5、本活动由中国邮政储蓄银行优惠发放，具体使用如有不明之处，请联系银行。'''
                    alidiscountcoupon_data['activity_description'] = description
                    alidiscountcoupon_data['publish_start_time'] = available_begin_time
                    alidiscountcoupon_data['publish_end_time'] = available_end_time
                    alidiscountcoupon_data['max_number'] = int(Decimal(data_dict['data']['dataVO']['form']['budgetAmt'])/Decimal(data_dict['data']['dataVO']['form']['overReduceAmount']))
                    alidiscountcoupon_data['remain_number'] = int(Decimal(data_dict['data']['dataVO']['form']['budgetAmt'])/Decimal(data_dict['data']['dataVO']['form']['overReduceAmount']))
                    max_number_by_user = data_dict['data']['dataVO']['form']['totalCountLimit']
                    alidiscountcoupon_data['max_number_by_user'] = max_number_by_user
                    alidiscountcoupon_data['coupon_type'] = 2
                    alidiscountcoupon_data['coupon_channel'] = 1
                    alidiscountcoupon_data['amount'] = coupon_amount
                    alidiscountcoupon_data['transaction_minimum'] = transaction_minimum
                    alidiscountcoupon_data['coupon_status'] = 3
                    alidiscountcoupon_data['is_need_auth'] = 1
                    alidiscountcoupon_data['coupon_way'] = coupon_way
                    alidiscountcoupon_data['platform_id'] = platform.id
                    alidiscountcoupon_data['available_merchants'] = ''
                    alidiscountcoupon_data['is_check_identity'] = 1
                    alidiscountcoupon, create = AliDiscountCoupon.objects.get_or_create(template_id=template_id, defaults=alidiscountcoupon_data)
                    if create:
                        alidiscountcouponchannelcommonvoucher_data = {}
                        if data_dict['data']['dataVO']['form']['bankCardType'] == 'DEBIT':
                            bankcard_type = 2
                        elif data_dict['data']['dataVO']['form']['bankCardType'] == 'CREDIT':
                            bankcard_type = 1
                        elif data_dict['data']['dataVO']['form']['bankCardType'] == 'DEBIT_CREDIT':
                            bankcard_type = 3
                        else:
                            bankcard_type =4
                        alidiscountcouponchannelcommonvoucher_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                        alidiscountcouponchannelcommonvoucher_data['bankcard_type'] = bankcard_type
                        alidiscountcouponchannelcommonvoucher_data['principal_name'] = '中国邮政储蓄银行'
                        alidiscountcouponchannelcommonvoucher_data['biz_scene_id'] = 7
                        if data_dict['data']['dataVO']['form']['useTimeType'] == 'ABSOLUTELY':
                            alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 2
                            alidiscountcouponchannelcommonvoucher_data['start_fixed_time'] = datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['startFixedTime']/1000)
                            alidiscountcouponchannelcommonvoucher_data['end_fixed_time'] =  datetime.datetime.fromtimestamp(data_dict['data']['dataVO']['form']['endFixedTime']/1000)
                        elif data_dict['data']['dataVO']['form']['useTimeType'] == 'RELATIVE':
                            alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 3
                            alidiscountcouponchannelcommonvoucher_data['invalid_day'] = data_dict['data']['dataVO']['form']['invalidDays']
                        else:
                            alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 4
                            alidiscountcouponchannelcommonvoucher_data['invalid_day'] = data_dict['data']['dataVO']['form']['invalidDays']
                        if 'countLimitRoundingType' in data_dict['data']['dataVO']['form']:
                            if data_dict['data']['dataVO']['form']['countLimitRoundingType'] == 'DAYS':
                                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 1
                            elif data_dict['data']['dataVO']['form']['countLimitRoundingType'] == 'MONTHS':
                                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 2
                            else:
                                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 4
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = data_dict['data']['dataVO']['form']['frequencyCountLimit']
                        else:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 3
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 1
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = data_dict['data']['dataVO']['form']['totalCountLimit']
                        alidiscountcouponchannelcommonvoucher_data['budget_amount'] = Decimal(data_dict['data']['dataVO']['form']['budgetAmt'])
                        AliDiscountCouponChannelCommonVoucher.objects.create(**alidiscountcouponchannelcommonvoucher_data)
                    AliDiscountCouponOperationRecord.objects.create(
                        alidiscountcoupon_id=alidiscountcoupon.id,
                        create_user_id=user.id,
                        remark='创建活动'
                    )
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '添加成功', 'data': AliDiscountCouponLevelRetrieveModelSerializer(alidiscountcoupon).data}, status=status.HTTP_200_OK)
                except Exception as e:
                    logger.error(e)
                    # 事务回滚
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(coupon_channel) == '2':
            if not template_id:
                return Response({'error': '微信活动请传批次号id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=1).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            # activity = AliDiscountCoupon.objects.filter(template_id=template_id)
            # if activity:
            #     return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_stockinfo(template_id, platform)
            if 'code' in data_dict:
                return Response({'error': data_dict['message']}, status=status.HTTP_400_BAD_REQUEST)
            if data_dict['stock_type'] != 'NORMAL':
                if str(coupon_way) not in ['9', '10']:
                    return Response({'error': '活动类型为立减与折扣,请选择对应派发方式'}, status=status.HTTP_400_BAD_REQUEST)
            if data_dict['stock_use_rule']['coupon_type'] != 'NORMAL':
                return Response({'error': '暂不支持减至券批次活动'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()

                # 暴力回滚
                try:
                    alidiscountcoupon_data = {}
                    if str(coupon_way) == '3':
                        alidiscountcoupon_data['start_enable_time'] = '1970-01-01 09:00:00'
                    alidiscountcoupon_data['user_id'] = user.id
                    alidiscountcoupon_data['level_id'] = level.id
                    alidiscountcoupon_data['template_id'] = template_id
                    alidiscountcoupon_data['activity_name'] = name
                    alidiscountcoupon_data['distribution_platform_id'] = distribution_platform_id
                    alidiscountcoupon_data['name'] = data_dict['stock_name']
                    transaction_minimum = (Decimal(data_dict['stock_use_rule']['fixed_normal_coupon']['transaction_minimum']) / Decimal('100')).quantize(Decimal('0.00'))
                    coupon_amount = (Decimal(data_dict['stock_use_rule']['fixed_normal_coupon']['coupon_amount']) / Decimal('100')).quantize(Decimal('0.00'))
                    alidiscountcoupon_data['floor_amount'] = f"满{transaction_minimum}元减{coupon_amount}元"
                    alidiscountcoupon_data['brand_name'] = "中国邮政储蓄银行"
                    available_begin_time = datetime.datetime.strptime(data_dict['available_begin_time'].replace('+08:00', ''), '%Y-%m-%dT%H:%M:%S')
                    available_end_time = datetime.datetime.strptime(data_dict['available_end_time'].replace('+08:00', ''), '%Y-%m-%dT%H:%M:%S')
                    alidiscountcoupon_data['activity_valid_period'] = f"到{available_end_time.strftime('%Y年%m月%d日')}"
                    alidiscountcoupon_data['activity_description'] = data_dict['description']
                    alidiscountcoupon_data['publish_start_time'] = available_begin_time
                    alidiscountcoupon_data['publish_end_time'] = available_end_time
                    alidiscountcoupon_data['max_number'] = data_dict['stock_use_rule']['max_coupons']
                    alidiscountcoupon_data['remain_number'] = data_dict['stock_use_rule']['max_coupons']
                    max_number_by_day = data_dict['stock_use_rule']['max_amount_by_day'] / data_dict['stock_use_rule']['fixed_normal_coupon']['transaction_minimum']
                    max_number_by_user = data_dict['stock_use_rule']['max_coupons_per_user']
                    alidiscountcoupon_data['max_number_by_day'] = max_number_by_day
                    alidiscountcoupon_data['max_number_by_user'] = max_number_by_user
                    alidiscountcoupon_data['coupon_type'] = 8
                    alidiscountcoupon_data['coupon_channel'] = 2
                    alidiscountcoupon_data['amount'] = coupon_amount
                    alidiscountcoupon_data['transaction_minimum'] = transaction_minimum
                    alidiscountcoupon_data['coupon_status'] = 3
                    alidiscountcoupon_data['is_need_auth'] = 1
                    alidiscountcoupon_data['coupon_way'] = coupon_way
                    alidiscountcoupon_data['platform_id'] = platform.id
                    alidiscountcoupon_data['available_merchants'] = ''
                    alidiscountcoupon_data['is_check_identity'] = 0
                    if fn_order_id:
                        alidiscountcoupon_data['fn_order_id'] = fn_order_id
                    alidiscountcoupon, create = AliDiscountCoupon.objects.get_or_create(template_id=template_id, defaults=alidiscountcoupon_data)
                    if create:
                        alidiscountcouponchannelcommonvoucher_data = {}
                        alidiscountcouponchannelcommonvoucher_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                        alidiscountcouponchannelcommonvoucher_data['bankcard_type'] = 3
                        alidiscountcouponchannelcommonvoucher_data['principal_name'] = '中国邮政储蓄银行'
                        alidiscountcouponchannelcommonvoucher_data['biz_scene_id'] = 7
                        alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 2
                        alidiscountcouponchannelcommonvoucher_data['start_fixed_time'] = available_begin_time
                        alidiscountcouponchannelcommonvoucher_data['end_fixed_time'] = available_end_time
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 0
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 1
                        alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = max_number_by_user
                        alidiscountcouponchannelcommonvoucher_data['budget_amount'] = (Decimal(data_dict['stock_use_rule']['max_amount']) / Decimal('100')).quantize(Decimal('0.00'))
                        AliDiscountCouponChannelCommonVoucher.objects.create(**alidiscountcouponchannelcommonvoucher_data)
                        AliDiscountCouponOperationRecord.objects.create(
                            alidiscountcoupon_id=alidiscountcoupon.id,
                            create_user_id=user.id,
                            remark='创建活动'
                        )
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '添加成功', 'data': AliDiscountCouponLevelRetrieveModelSerializer(alidiscountcoupon).data}, status=status.HTTP_200_OK)
                except Exception as e:
                    logger.error(e)
                    # 事务回滚
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        elif str(coupon_channel) == '3':
            if not all([publish_start_time, publish_end_time]):
                return Response({'error': '请设置活动时间'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                publish_start_time = datetime.datetime.strptime(publish_start_time, '%Y-%m-%d %H:%M:%S')
                publish_end_time = datetime.datetime.strptime(publish_end_time, '%Y-%m-%d %H:%M:%S')
            except:
                return Response({'error': '活动时间格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            if publish_end_time <= datetime.datetime.now():
                return Response({'error': '活动结束时间须大于当前时间'}, status=status.HTTP_400_BAD_REQUEST)
            if publish_end_time <= publish_start_time:
                return Response({'error': '活动结束时间须大于开始时间'}, status=status.HTTP_400_BAD_REQUEST)
            if not activity_description:
                return Response({'error': '请上传活动说明'}, status=status.HTTP_400_BAD_REQUEST)
            if not max_number:
                return Response({'error': '请设置活动最大派发数'}, status=status.HTTP_400_BAD_REQUEST)
            try:
                max_number = int(max_number)
            except:
                return Response({'error': '活动最大派发数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            if str(max_number_by_day) == '1':
                if not max_number_by_day_count:
                    return Response({'error': '请上传活动每天最大派发数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    max_number_by_day_count = int(max_number_by_day_count)
                except:
                    return Response({'error': '活动每天最大派发数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                if max_number_by_day_count > max_number:
                    return Response({'error': '活动每人最大领取数不得大于活动总数'}, status=status.HTTP_400_BAD_REQUEST)
            if str(max_number_by_user) == '1':
                if not max_number_by_user_count:
                    return Response({'error': '请上传活动每人最大领取数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    max_number_by_user_count = int(max_number_by_user_count)
                except:
                    return Response({'error': '活动每人最大领取数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                if max_number_by_user_count > max_number:
                    return Response({'error': '活动每人最大领取数不得大于活动总数'}, status=status.HTTP_400_BAD_REQUEST)
            if str(usetime_type) not in ['1', '2', '3', '4']:
                return Response({'error': '优惠券有效期参数有误'}, status=status.HTTP_400_BAD_REQUEST)
            alidiscountcoupon_data = {}
            if str(coupon_way) == '3':
                alidiscountcoupon_data['start_enable_time'] = '1970-01-01 09:00:00'
            alidiscountcoupon_data['user_id'] = user.id
            alidiscountcoupon_data['level_id'] = level.id
            template_id = f'MC{"%03d" % randint(0, 999)}INFLY{"%06d" % randint(0, 999999)}'
            alidiscountcoupon_data['template_id'] = template_id
            alidiscountcoupon_data['activity_name'] = name
            alidiscountcoupon_data['distribution_platform_id'] = distribution_platform_id
            alidiscountcoupon_data['name'] = name
            alidiscountcoupon_data['brand_name'] = "中国邮政储蓄银行"
            alidiscountcoupon_data['activity_valid_period'] = f"到{publish_end_time.strftime('%Y年%m月%d日')}"
            alidiscountcoupon_data['activity_description'] = activity_description
            alidiscountcoupon_data['publish_start_time'] = publish_start_time
            alidiscountcoupon_data['publish_end_time'] = publish_end_time
            alidiscountcoupon_data['max_number'] = max_number
            alidiscountcoupon_data['remain_number'] = max_number
            alidiscountcoupon_data['max_number_by_day'] = max_number_by_day_count
            alidiscountcoupon_data['max_number_by_user'] = max_number_by_user_count
            alidiscountcoupon_data['coupon_type'] = coupon_type
            alidiscountcoupon_data['coupon_channel'] = 3
            alidiscountcoupon_data['coupon_status'] = 3
            alidiscountcoupon_data['is_need_auth'] = 1
            alidiscountcoupon_data['coupon_way'] = coupon_way
            alidiscountcoupon_data['available_merchants'] = ''
            alidiscountcoupon_data['is_check_identity'] = 0
            alidiscountcouponchannelcommonvoucher_data = {}
            alidiscountcouponchannelcommonvoucher_data['bankcard_type'] = 4
            alidiscountcouponchannelcommonvoucher_data['principal_name'] = '中国邮政储蓄银行'
            alidiscountcouponchannelcommonvoucher_data['biz_scene_id'] = 7
            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 0
            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 1
            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = max_number_by_user
            alidiscountcouponchannelcommonvoucher_data['budget_amount'] = 0
            if fn_order_id:
                alidiscountcoupon_data['fn_order_id'] = fn_order_id
            if str(coupon_type) == '6':
                alidiscountcoupon_data['floor_amount'] = '可兑换指定商品一份'
            elif str(coupon_type) == '9':
                if not transaction_minimum:
                    return Response({'error': '满减券请上传使用门槛'}, status=status.HTTP_400_BAD_REQUEST)
                if not amount:
                    return Response({'error': '满减券请设置面额'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    transaction_minimum = Decimal(transaction_minimum)
                except:
                    return Response({'error': '门槛参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    amount = Decimal(amount)
                except:
                    return Response({'error': '面额参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
                if amount >= transaction_minimum:
                    return Response({'error': '使用门槛不得小于券面额'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcoupon_data['transaction_minimum'] = transaction_minimum
                alidiscountcoupon_data['amount'] = amount
                alidiscountcoupon_data['floor_amount'] = f'满{transaction_minimum}元减{amount}元'

            else:
                return Response({'error': '商家券类型有误'}, status=status.HTTP_400_BAD_REQUEST)
            alidiscountcoupon, create = AliDiscountCoupon.objects.get_or_create(template_id=template_id, defaults=alidiscountcoupon_data)
            alidiscountcouponchannelcommonvoucher_data['alidiscountcoupon_id'] = alidiscountcoupon.id
            if str(join_limit_by_bay) == '1':
                if not join_limit_by_bay_count:
                    return Response({'error': '请上传活动每人每天最大领取数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    join_limit_by_bay_count = int(join_limit_by_bay_count)
                except:
                    return Response({'error': '活动每人每天最大领取数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 1
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = join_limit_by_bay_count
            elif str(join_limit_by_bay) == '2':
                if not join_limit_by_bay_count:
                    return Response({'error': '请上传活动每人每周最大领取数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    join_limit_by_bay_count = int(join_limit_by_bay_count)
                except:
                    return Response({'error': '活动每人每周最大领取数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 4
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = join_limit_by_bay_count
            elif str(join_limit_by_bay) == '3':
                if not join_limit_by_bay_count:
                    return Response({'error': '请上传活动每人每月最大领取数'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    join_limit_by_bay_count = int(join_limit_by_bay_count)
                except:
                    return Response({'error': '活动每人每月最大领取数须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 2
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = join_limit_by_bay_count
            else:
                alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 3
            if str(usetime_type) == '1':
                alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 2
                alidiscountcouponchannelcommonvoucher_data['start_fixed_time'] = publish_start_time
                alidiscountcouponchannelcommonvoucher_data['end_fixed_time'] = publish_end_time
            elif str(usetime_type) == '2':
                try:
                    start_fixed_time = datetime.datetime.strptime(start_fixed_time, '%Y-%m-%d %H:%M:%S')
                    end_fixed_time = datetime.datetime.strptime(end_fixed_time, '%Y-%m-%d %H:%M:%S')
                except:
                    return Response({'error': '优惠券有效时间格式有误'}, status=status.HTTP_400_BAD_REQUEST)
                if end_fixed_time <= datetime.datetime.now():
                    return Response({'error': '优惠券有效时间须大于当前时间'}, status=status.HTTP_400_BAD_REQUEST)
                if end_fixed_time <= start_fixed_time:
                    return Response({'error': '优惠券有效时间须大于开始时间'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 2
                alidiscountcouponchannelcommonvoucher_data['start_fixed_time'] = start_fixed_time
                alidiscountcouponchannelcommonvoucher_data['end_fixed_time'] = end_fixed_time
            elif str(usetime_type) == '3':
                if not invalid_day:
                    return Response({'error': '请上传有效期期限'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    invalid_day = int(invalid_day)
                except:
                    return Response({'error': '有效期期限须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 3
                alidiscountcouponchannelcommonvoucher_data['invalid_day'] = invalid_day
            else:
                if not invalid_day:
                    return Response({'error': '请上传有效期期限'}, status=status.HTTP_400_BAD_REQUEST)
                try:
                    invalid_day = int(invalid_day)
                except:
                    return Response({'error': '有效期期限须为正整数'}, status=status.HTTP_400_BAD_REQUEST)
                alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 4
                alidiscountcouponchannelcommonvoucher_data['invalid_day'] = invalid_day
            AliDiscountCouponChannelCommonVoucher.objects.get_or_create(defaults=alidiscountcouponchannelcommonvoucher_data, alidiscountcoupon_id=alidiscountcoupon.id)
            AliDiscountCouponOperationRecord.objects.create(
                alidiscountcoupon_id=alidiscountcoupon.id,
                create_user_id=user.id,
                remark='创建活动'
            )
            return Response({'success': '添加成功', 'data': AliDiscountCouponLevelRetrieveModelSerializer(alidiscountcoupon).data}, status=status.HTTP_200_OK)
        elif str(coupon_channel) == '5':
            if not template_id:
                return Response({'error': '美团活动请传批次号id'}, status=status.HTTP_400_BAD_REQUEST)
            activity = AliDiscountCoupon.objects.filter(template_id=template_id, coupon_channel=5)
            if activity:
                return Response({'error': '重复上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
            if not platform_id:
                return Response({'error': '请选择对应活动平台'}, status=status.HTTP_400_BAD_REQUEST)
            platform = Channel.objects.filter(id=platform_id, channel_type=5).first()
            if not platform:
                return Response({'error': '无效平台参数'}, status=status.HTTP_400_BAD_REQUEST)
            data_dict = get_meituan_acitivty(template_id, platform)
            if data_dict['status'] == 'fail':
                return Response({'error': data_dict['errorMsg']}, status=status.HTTP_400_BAD_REQUEST)
            if not data_dict['data']:
                return Response({'error': '无效批次号'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()

                # 暴力回滚
                try:
                    alidiscountcoupon_data = {}
                    if str(coupon_way) == '3':
                        alidiscountcoupon_data['start_enable_time'] = '1970-01-01 09:00:00'
                    alidiscountcoupon_data['user_id'] = user.id
                    alidiscountcoupon_data['level_id'] = level.id
                    alidiscountcoupon_data['template_id'] = template_id
                    alidiscountcoupon_data['activity_name'] = name
                    alidiscountcoupon_data['distribution_platform_id'] = distribution_platform_id
                    alidiscountcoupon_data['name'] = data_dict['data']['titleShow']
                    transaction_minimum = data_dict['data']['discountDetaiDtos'][0]['quotaValue']
                    coupon_amount = data_dict['data']['discountDetaiDtos'][0]['reduceValue']
                    alidiscountcoupon_data['floor_amount'] = f"满{transaction_minimum}元减{coupon_amount}元"
                    alidiscountcoupon_data['brand_name'] = '中国邮政储蓄储蓄卡'
                    available_begin_time = datetime.datetime.strptime(data_dict['data']['validBeginTime'], "%Y-%m-%d %H:%M:%S")
                    available_end_time = datetime.datetime.strptime(data_dict['data']['assignEndTime'], "%Y-%m-%d %H:%M:%S")
                    alidiscountcoupon_data['activity_valid_period'] = f"到{available_end_time.strftime('%Y年%m月%d日')}"
                    alidiscountcoupon_data['activity_description'] = data_dict['data']['restrictShow']
                    alidiscountcoupon_data['publish_start_time'] = available_begin_time
                    alidiscountcoupon_data['publish_end_time'] = available_end_time
                    alidiscountcoupon_data['max_number'] = int(data_dict['data']['totalCount'])
                    alidiscountcoupon_data['remain_number'] = int(data_dict['data']['totalCount'])
                    max_number_by_user = data_dict['data']['receiveLimitDto']['userReceiveLimit']
                    alidiscountcoupon_data['max_number_by_user'] = max_number_by_user if max_number_by_user else None
                    alidiscountcoupon_data['coupon_type'] = 2
                    alidiscountcoupon_data['coupon_channel'] = 5
                    alidiscountcoupon_data['amount'] = coupon_amount
                    alidiscountcoupon_data['transaction_minimum'] = transaction_minimum
                    alidiscountcoupon_data['coupon_status'] = 3
                    alidiscountcoupon_data['is_need_auth'] = 1
                    alidiscountcoupon_data['coupon_way'] = coupon_way
                    alidiscountcoupon_data['platform_id'] = platform.id
                    alidiscountcoupon_data['available_merchants'] = ''
                    alidiscountcoupon_data['is_check_identity'] = 0
                    alidiscountcoupon, create = AliDiscountCoupon.objects.get_or_create(template_id=template_id, defaults=alidiscountcoupon_data)
                    if create:
                        alidiscountcouponchannelcommonvoucher_data = {}
                        # if data_dict['data']['bankType'] == 0:
                        #     bankcard_type = 4
                        # elif data_dict['data']['dataVO']['form']['bankCardType'] == 'CREDIT':
                        #     bankcard_type = 1
                        # elif data_dict['data']['dataVO']['form']['bankCardType'] == 'DEBIT_CREDIT':
                        #     bankcard_type = 3
                        # else:
                        bankcard_type = 3
                        alidiscountcouponchannelcommonvoucher_data['alidiscountcoupon_id'] = alidiscountcoupon.id
                        alidiscountcouponchannelcommonvoucher_data['bankcard_type'] = bankcard_type
                        alidiscountcouponchannelcommonvoucher_data['principal_name'] = '中国邮政储蓄银行'
                        alidiscountcouponchannelcommonvoucher_data['biz_scene_id'] = 7
                        alidiscountcouponchannelcommonvoucher_data['usetime_type'] = 3
                        alidiscountcouponchannelcommonvoucher_data['invalid_day'] = data_dict['data']['countDownDays']
                        if data_dict['data']['receiveLimitDto']['userReceiveLimit']:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 1
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = data_dict['data']['receiveLimitDto']['userReceiveLimit']
                        else:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user'] = 2
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_user_count'] = 0

                        if data_dict['data']['receiveLimitDto']['daySendLimit']:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 1
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = data_dict['data']['receiveLimitDto']['daySendLimit']
                        elif data_dict['data']['receiveLimitDto']['weekSendLimit']:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 4
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = data_dict['data']['receiveLimitDto']['weekSendLimit']
                        elif data_dict['data']['receiveLimitDto']['monthSendLimit']:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 2
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = data_dict['data']['receiveLimitDto']['monthSendLimit']
                        else:
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay'] = 3
                            alidiscountcouponchannelcommonvoucher_data['join_limit_by_bay_count'] = 0
                        alidiscountcouponchannelcommonvoucher_data['budget_amount'] = Decimal(data_dict['data']['totalCount']) * Decimal(coupon_amount)
                        AliDiscountCouponChannelCommonVoucher.objects.create(**alidiscountcouponchannelcommonvoucher_data)
                    AliDiscountCouponOperationRecord.objects.create(
                        alidiscountcoupon_id=alidiscountcoupon.id,
                        create_user_id=user.id,
                        remark='创建活动'
                    )
                    transaction.savepoint_commit(save_id)
                    return Response({'success': '添加成功', 'data': AliDiscountCouponLevelRetrieveModelSerializer(alidiscountcoupon).data}, status=status.HTTP_200_OK)
                except Exception as e:
                    logger.error(e)
                    # 事务回滚
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '添加失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({'error': '无效活动类型参数'}, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        coupon_way = self.request.data.get('coupon_way', None)
        publish_start_time = self.request.data.get('publish_start_time', None)
        publish_end_time = self.request.data.get('publish_end_time', None)
        is_need_auth = self.request.data.get('is_need_auth', None)
        is_white = self.request.data.get('is_white', None)
        is_union = self.request.data.get('is_union', None)
        available_merchants = self.request.data.get('available_merchants', None)
        activity_description = self.request.data.get('activity_description', None)
        max_number = self.request.data.get('max_number', None)
        distributed_limit_by_time = self.request.data.get('distributed_limit_by_time', None)
        distributed_limit_by_time_rules = self.request.data.get('distributed_limit_by_time_rules', [])
        level_id = self.request.data.get('level_id', None)
        remark = self.request.data.get('remark', None)
        distribution_platform_id = self.request.data.get('distribution_platform_id', None)
        drawdown_platform_id = self.request.data.get('drawdown_platform_id', None)
        is_use_path = self.request.data.get('is_use_path', None)
        use_path = self.request.data.get('use_path', None)
        use_appid = self.request.data.get('use_appid', None)
        is_self = self.request.data.get('is_self', None)
        goods_tag = self.request.data.get('goods_tag', None)
        max_number_by_day = self.request.data.get('max_number_by_day', None)
        is_max_number_by_day = self.request.data.get('is_max_number_by_day', None)
        is_check_identity = self.request.data.get('is_check_identity', None)
        banner_short = self.request.FILES.get('banner_short', None)
        banner_long = self.request.FILES.get('banner_long', None)
        is_psbc_card = self.request.data.get('is_psbc_card', None)
        join_limit_by_location = self.request.data.get('join_limit_by_location', None)
        is_keguan = self.request.data.get('is_keguan', '')
        pushEventIds = self.request.data.get('pushEventIds', '')
        bankcard_type = self.request.data.get('bankcard_type', '')
        usage_scenario = self.request.data.get('usage_scenario', '')
        if str(is_keguan) == '1':
            if not pushEventIds:
                return Response({'error': '请上传营销事件ID'}, status=status.HTTP_400_BAD_REQUEST)
            if not instance.level.account_nine:
                return Response({'error': '活动所属机构尚未绑定9位机构号,请联系管理员处理'}, status=status.HTTP_400_BAD_REQUEST)
            instance.is_keguan = 1
            instance.pushEventIds = pushEventIds
            keguan_data = {}
            keguan_data['sourceId'] = instance.template_id
            keguan_data['pushEventIds'] = str(pushEventIds).split('|')
            keguan_data['orgNo'] = instance.level.account_nine
            keguan_data['activityName'] = instance.activity_name
            keguan_data['startTime'] = instance.publish_start_time.strftime("%Y-%m-%dT%H:%M:%S.120+08:00")
            keguan_data['endTime'] = instance.publish_end_time.strftime("%Y-%m-%dT%H:%M:%S.120+08:00")
            keguan_result = ylx_api('ThirdActInfoSyncGdCrm', keguan_data)
            if keguan_result['meta']['code'] != 200:
                return Response({'error': f"同步客管系统失败,原因:{keguan_result['meta']['msg']}"}, status=status.HTTP_400_BAD_REQUEST)
            AliDiscountCouponKeguanRecords.objects.create(alidiscountcoupon_id=instance.id, operate_user_id=user.id, operate_type=1)
        elif str(is_keguan) == '0':
            instance.is_keguan = 0
            AliDiscountCouponKeguanRecords.objects.create(alidiscountcoupon_id=instance.id, operate_user_id=user.id, operate_type=2)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()

            # 暴力回滚
            try:
                # if str(coupon_way) in ['1', '2', '3']:
                #     instance.coupon_way = coupon_way
                operation_remark = ''
                if publish_start_time and publish_end_time:
                    try:
                        publish_start_time = datetime.datetime.strptime(publish_start_time, "%Y-%m-%d %H:%M:%S")
                        publish_end_time = datetime.datetime.strptime(publish_end_time, "%Y-%m-%d %H:%M:%S")
                    except:
                        return Response({'error': '活动时间区间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
                    if publish_start_time >= publish_end_time:
                        return Response({'error': '活动开始时间须大于结束时间!'}, status=status.HTTP_400_BAD_REQUEST)
                    if datetime.datetime.now() >= publish_end_time:
                        return Response({'error': '活动结束时间须大于当前时间!'}, status=status.HTTP_400_BAD_REQUEST)
                    operation_remark += f'修改活动时间,原活动时间:{instance.publish_start_time.strftime("%Y-%m-%d %H:%M:%S")}至{instance.publish_end_time.strftime("%Y-%m-%d %H:%M:%S")};'
                    instance.publish_start_time = publish_start_time
                    instance.publish_end_time = publish_end_time
                    if instance.coupon_status == 2:
                        instance.coupon_status = 3
                if str(is_need_auth) in ['0', '1']:
                    operation_remark += f'修改是否需要认证,原活动:{instance.get_is_need_auth_display()};'
                    instance.is_need_auth = is_need_auth
                if str(is_white) in ['0', '1']:
                    operation_remark += f'修改是否需要白名单校验,原活动:{instance.get_is_white_display()};'
                    instance.is_white = is_white
                if str(is_union) in ['0', '1']:
                    operation_remark += f'修改是否友商联盟,原活动:{instance.get_is_union_display()};'
                    instance.is_union = is_union
                if available_merchants:
                    operation_remark += f'修改参与活动商户说明,原活动:{instance.available_merchants};'
                    instance.available_merchants = available_merchants
                if activity_description:
                    operation_remark += f'修改活动使用说明,原活动:{instance.activity_description};'
                    instance.activity_description = activity_description
                if max_number:
                    try:
                        max_number = int(max_number)
                    except:
                        return Response({'error': '活动最大派发数参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
                    operation_remark += f'修改活动总额度,原活动:{instance.max_number};'
                    old_max_number = instance.max_number
                    instance.max_number = max_number
                    instance.remain_number = instance.remain_number + max_number - old_max_number
                if str(join_limit_by_location) in ['2', '1']:
                    channelcommonvoucher = instance.alidiscountcouponchannelcommonvoucher
                    operation_remark += f'修改活动地理位置参与限制,原活动:{channelcommonvoucher.get_join_limit_by_location_display()};'
                    channelcommonvoucher.join_limit_by_location = join_limit_by_location
                    channelcommonvoucher.save()
                if str(distributed_limit_by_time) in ['1', '2']:
                    channelcommonvoucher = instance.alidiscountcouponchannelcommonvoucher
                    if str(distributed_limit_by_time) == '1' and channelcommonvoucher.distributed_limit_by_time == 2:
                        if not distributed_limit_by_time_rules:
                            return Response({'error': '请上传固定派发时间规则!'}, status=status.HTTP_400_BAD_REQUEST)
                    channelcommonvoucher.distributed_limit_by_time = distributed_limit_by_time
                    channelcommonvoucher.save()
                    alidiscountcoupondistributedlimit_set = channelcommonvoucher.alidiscountcoupondistributedlimit_set.all().delete()
                    for rule in distributed_limit_by_time_rules:
                        start_enable_time = rule['start_enable_time']
                        end_enable_time = rule['end_enable_time']
                        weeks = rule['weeks']
                        try:
                            start_enable_time = datetime.datetime.strptime(f'1970-01-01 {start_enable_time}', "%Y-%m-%d %H:%M:%S")
                            end_enable_time = datetime.datetime.strptime(f'1970-01-01 {end_enable_time}', "%Y-%m-%d %H:%M:%S")
                        except:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '派发时间区间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
                        if start_enable_time >= end_enable_time:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '派发时间区间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
                        AliDiscountCouponDistributedLimit.objects.create(
                            ali_discount_coupon_common_voucher_id=channelcommonvoucher.id,
                            start_enable_time=start_enable_time,
                            end_enable_time=end_enable_time,
                            weeks=weeks
                        )
                if bankcard_type:
                    channelcommonvoucher = instance.alidiscountcouponchannelcommonvoucher
                    channelcommonvoucher.bankcard_type = bankcard_type
                    channelcommonvoucher.save()
                if usage_scenario:
                    instance.usage_scenario = usage_scenario
                if level_id:
                    instance.level_id = level_id
                if str(is_psbc_card) in ['0', '1']:
                    instance.is_psbc_card = int(is_psbc_card)
                if remark:
                    operation_remark += f'修改备注,原活动:{instance.remark};'
                    instance.remark = remark
                if distribution_platform_id:
                    try:
                        distribution_platform = AliDiscountCouponDistributionPlatform.objects.get(id=distribution_platform_id)
                    except:
                        return Response({'error': '无效派发平台参数'}, status=status.HTTP_400_BAD_REQUEST)
                    if instance.distribution_platform:
                        operation_remark += f'修改派发平台,原活动:{instance.distribution_platform.platform_name};'
                    else:
                        operation_remark += f'修改派发平台,原活动:无;'
                    instance.distribution_platform_id = distribution_platform_id
                if drawdown_platform_id:
                    try:
                        drawdown_platform = AliDiscountCouponDistributionPlatform.objects.get(id=drawdown_platform_id)
                    except:
                        return Response({'error': '无效派发平台参数'}, status=status.HTTP_400_BAD_REQUEST)
                    if instance.drawdown_platform_id:
                        operation_remark += f'修改派发平台,原活动:{instance.drawdown_platform.platform_name};'
                    else:
                        operation_remark += f'修改派发平台,原活动:无;'
                    instance.drawdown_platform_id = drawdown_platform_id
                if str(is_use_path) == '1':
                    if not all([use_appid, use_path]):
                        return Response({'error': '请上传跳转参数'}, status=status.HTTP_400_BAD_REQUEST)
                    if str(is_self) not in ['0', '1']:
                        return Response({'error': '跳转平台参数有误'}, status=status.HTTP_400_BAD_REQUEST)
                    instance.is_use_path = is_use_path
                    instance.use_path = use_path
                    instance.use_appid = use_appid
                    instance.is_self = is_self
                if str(is_use_path) == '0':
                    instance.is_use_path = is_use_path
                if goods_tag:
                    instance.goods_tag = goods_tag
                if str(is_max_number_by_day) == '1':
                    instance.max_number_by_day = max_number_by_day
                elif str(is_max_number_by_day) == '0':
                    instance.max_number_by_day = 0
                if str(is_check_identity) == '1':
                    instance.is_check_identity = 1
                elif str(is_check_identity) == '0':
                    instance.is_check_identity = 0
                if banner_short:
                    banner_short_str = banner_short.read()
                    tmpIm = io.BytesIO(banner_short_str)
                    image = Image.open(tmpIm)
                    width, height = image.size
                    if width != 750 or height != 268:
                        return Response({'error': 'banner短图尺寸不符,图片规格要求750*268'}, status=status.HTTP_400_BAD_REQUEST)
                    banner_short_img = pic_upload(banner_short_str, key=None)
                    instance.banner_short = banner_short_img
                if banner_long:
                    banner_long_str = banner_long.read()
                    tmpIm = io.BytesIO(banner_long_str)
                    image = Image.open(tmpIm)
                    width, height = image.size
                    if width != 750 or height != 460:
                        return Response({'error': 'banner长图尺寸不符,图片规格要求750*460'}, status=status.HTTP_400_BAD_REQUEST)
                    banner_long_img = pic_upload(banner_long_str, key=None)
                    instance.banner_long = banner_long_img
                instance.save()
                AliDiscountCouponOperationRecord.objects.create(
                    alidiscountcoupon_id=instance.id,
                    create_user_id=user.id,
                    remark=operation_remark
                )
                transaction.savepoint_commit(save_id)
                return Response({'success': '修改成功!'}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update_white_table(self, request):
        activity_id = self.request.data.get('activity_id', None)
        mobile_array = self.request.data.get('mobile_array', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()

            # 暴力回滚
            try:
                alidiscountcouponwhitetable_set = instance.alidiscountcouponwhitetable_set.all().delete()
                for mobile in mobile_array:
                    if not re.match(r'^1[3-9]\d{9}$', mobile):
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': f'{mobile}非手机号格式'}, status=status.HTTP_400_BAD_REQUEST)
                    AliDiscountCouponWhiteTable.objects.create(alidiscountcoupon_id=activity_id, mobile=mobile)

                transaction.savepoint_commit(save_id)
                return Response({'success': '修改成功'}, status=status.HTTP_200_OK)
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def update_merchant(self, request):
        activity_id = self.request.data.get('activity_id', None)
        merchant_array = self.request.data.get('merchant_array', None)
        user = self.request.iser
        if user.platform == 2:
            check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=2, wx_is_enter=1)
        else:
            check_history = UpdateStockUsableMerchant.objects.filter(operation_user__platform=1, wx_is_enter=1)
        if check_history:
            is_enter = 4
        else:
            is_enter = 1
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(merchant_array, list):
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            updatestockusablemerchant_data = {}
            updatestockusablemerchant_data['user_id'] = user.id
            updatestockusablemerchant_data['test'] = json.dumps(merchant_array)
            updatestockusablemerchant_data['add_type'] = 2
            updatestockusablemerchant_data['alidiscountcoupon_id'] = instance.id
            updatestockusablemerchant_data['wx_is_enter'] = is_enter
            updatestockusablemerchant_data['ylx_is_enter'] = is_enter
            updatestockusablemerchant_data['operation_user_id'] = user.id
            updatestockusablemerchant_data['operation_time'] = datetime.datetime.now()
            history = UpdateStockUsableMerchant.objects.create(**updatestockusablemerchant_data)
            if is_enter == 1:
                update_stock_usable_merchant.delay({'id': history.id})
            # update_stock_usable_merchant({'id': history.id})
            return Response({'success': '提交修改成功,等待系统处理'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '修改失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)

    def partial_update(self, request, *args, **kwargs):
        instance = self.get_object()
        coupon_status = self.request.data.get('coupon_status', None)
        if instance.coupon_status == 2:
            return Response({'error': '活动已结束, 不可操作'}, status=status.HTTP_400_BAD_REQUEST)
        if str(coupon_status) == '1':
            alidiscountcoupon = AliDiscountCouponLevel.objects.filter(activity_id=instance.id)
            if not alidiscountcoupon and instance.coupon_way in [3, 2, 5]:
                alidiscountcoupon_data = {}
                alidiscountcoupon_data['level_id'] = instance.level_id
                alidiscountcoupon_data['activity_id'] = instance.id
                alidiscountcoupon_data['max_number'] = instance.max_number
                alidiscountcoupon_data['remain_number'] = instance.max_number
                alidiscountcoupon_data['p_max_number'] = instance.max_number
                alidiscountcoupon_data['p_remain_number'] = instance.max_number
                identify = random_str(randomlength=64)
                common_url = f'https://api.sutpay.com/customer/coupon/?identify={identify}'
                common_qrcode = f'youhuiquanyi/coupon/{identify}.png'
                common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
                alidiscountcoupon_data['common_url'] = common_url
                alidiscountcoupon_data['common_qrcode'] = common_qrcode
                alidiscountcoupon_data['identify'] = identify
                AliDiscountCouponLevel.objects.get_or_create(activity_id=instance.id, level_id=instance.level_id, defaults=alidiscountcoupon_data)
            instance.coupon_status = 1
            instance.save()
            return Response({'success': '开启活动成功'}, status=status.HTTP_200_OK)
        elif str(coupon_status) == '2':
            instance.coupon_status = 4
            instance.save()
            return Response({'success': '暂停活动成功'}, status=status.HTTP_200_OK)
        else:
            return Response({'error': '无效活动状态'}, status=status.HTTP_400_BAD_REQUEST)

    def discountcoupon_join_limit_level(self, request):
        activity_id = self.request.query_params.get('activity_id', None)
        search = self.request.query_params.get('search', None)
        if not activity_id:
            return Response({'error': '请传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            activity = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        level = activity.level
        if level.level == 0:
            queryset = Level.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id).order_by('level')
        else:
            queryset = Level.objects.filter(branch_id=level.id).order_by('level')
        queryset = queryset.exclude(alidiscountcouponlevel__activity_id=activity_id)
        if search:
            queryset = queryset.filter(Q(name__contains=search) | Q(account__contains=search))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = LevelListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = LevelListSerializer(queryset, many=True)
        return Response(serializer.data)

    def discountcoupon_join_limit_location(self, request):
        activity_id = self.request.data.get('activity_id', None)
        mobile_array = self.request.data.get('mobile_array', None)

    def white_table(self, request):
        activity_id = self.request.query_params.get('activity_id', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        alidiscountcouponwhitetable_set = instance.alidiscountcouponwhitetable_set.all().values_list('mobile', flat=True)
        return Response({'data': list(alidiscountcouponwhitetable_set)}, status=status.HTTP_200_OK)

    def export_activity_merchant(self, request):
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        try:
            instance = self.get_queryset().get(id=alidiscountcoupon_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        sql = f'''
        SELECT * FROM (SELECT e.*,f.activity_name,template_id FROM (SELECT c.*,d.prov_name,city_name,district_name,branch_name FROM (SELECT a.*,b.name,short_name,wyfMerchantID,level_id FROM (SELECT id,merchant_id,sub_mchid,alidiscountcoupon_id,channel_id FROM tb_ali_discount_coupon_merchant WHERE alidiscountcoupon_id={alidiscountcoupon_id})AS a LEFT JOIN (SELECT short_name,wyfMerchantID,name,id,level_id FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN(SELECT id,name AS activity_name,template_id FROM tb_ali_discount_coupon)AS f ON e.alidiscountcoupon_id=f.id)AS g LEFT JOIN (SELECT id,name AS channel_name FROM tb_channel)AS h ON g.channel_id=h.id;
        '''
        cursor.execute(sql)
        ziduan = ['id', '活动id', '活动名称', '微信批次号', '微信商户号', '所属通道', '微邮付商户号', '可用商户全称', '可用商户简称', '所属省公司', '所属市公司', '所属区县', '所属网点']
        cols = ['id', 'alidiscountcoupon_id', 'activity_name', 'template_id', 'sub_mchid', 'channel_name', 'wyfMerchantID', 'name', 'short_name', 'prov_name', 'city_name', 'district_name', 'branch_name']
        response = StreamingHttpResponse(self.get_activity_merchant_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('订单列表.csv'))
        return response

    def get_activity_merchant_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def allocation_max_number(self, request):
        user = self.request.iser
        data_array = self.request.data.get('data_array', None)
        activity_id = self.request.data.get('activity_id', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        level_list = get_level_list(instance.level)
        level_range = instance.level.level
        if instance.coupon_way == 1:
            if not data_array:
                return Response({'error': '缺少分配参数'}, status=status.HTTP_400_BAD_REQUEST)
            max_number__sum = instance.alidiscountcouponlevel_set.all().aggregate(Sum('max_number'))['max_number__sum']
            if max_number__sum:
                remain_number = instance.max_number - max_number__sum
            else:
                remain_number = instance.max_number
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    queryset_list = []
                    for allot in data_array:
                        if int(allot['level_id']) not in level_list:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                        if int(allot['count']) < 0:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '分配数量须大于0'}, status=status.HTTP_400_BAD_REQUEST)
                        if remain_number < int(allot['count']):
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '分配数据超过活动最大数'}, status=status.HTTP_400_BAD_REQUEST)
                        diacountcouponlevel_data = {}
                        diacountcouponlevel_data['level_id'] = allot['level_id']
                        diacountcouponlevel_data['activity_id'] = activity_id
                        diacountcouponlevel = AliDiscountCouponLevel.objects.filter(activity_id=activity_id, level_id=allot['level_id']).first()
                        if diacountcouponlevel and diacountcouponlevel.max_number != 0:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': f'{diacountcouponlevel.level.name}重复配置'}, status=status.HTTP_400_BAD_REQUEST)
                        if diacountcouponlevel:
                            diacountcouponlevel.max_number += int(allot['count'])
                            diacountcouponlevel.remain_number += int(allot['count'])
                            diacountcouponlevel.p_max_number += int(allot['count'])
                            diacountcouponlevel.p_remain_number += int(allot['count'])
                            diacountcouponlevel.save()
                        else:
                            diacountcouponlevel_data['max_number'] = int(allot['count'])
                            diacountcouponlevel_data['remain_number'] = int(allot['count'])
                            diacountcouponlevel_data['p_max_number'] = int(allot['count'])
                            diacountcouponlevel_data['p_remain_number'] = int(allot['count'])
                            diacountcouponlevel, create = AliDiscountCouponLevel.objects.get_or_create(defaults=diacountcouponlevel_data, activity_id=activity_id, level_id=allot['level_id'])
                        remain_number -= int(allot['count'])
                        queryset_list.append(diacountcouponlevel.id)
                    level_level_list = []
                    queryset_list1 = []
                    for i in range(4, level_range, -1):
                        level_level_list.append(i)
                        queryset = AliDiscountCouponLevel.objects.filter(id__in=queryset_list, level__level__in=level_level_list)
                        for query in queryset:
                            query_level = query.level
                            if i == 4:
                                diacountcouponlevel_level_id = query_level.parent_id
                            elif i == 3:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            elif i == 2:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                elif query_level.level == 3:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            else:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent.parent_id
                                elif query_level.level == 3:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                elif query_level.level == 2:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            instance1 = AliDiscountCouponLevel.objects.filter(level_id=diacountcouponlevel_level_id, activity_id=activity_id).first()
                            if not instance1:
                                instance1 = AliDiscountCouponLevel.objects.create(level_id=diacountcouponlevel_level_id, activity_id=activity_id, max_number=0)
                            queryset_list1.append(instance1.id)
                            p_max_number = instance1.p_max_number + query.max_number
                            p_remain_number = instance1.p_remain_number + query.remain_number
                            instance1.p_max_number = p_max_number
                            instance1.p_remain_number = p_remain_number
                            instance1.save()
                            relation_data = {
                                "parent_id": instance1.id,
                                "child_id": query.id
                            }
                            AliDiscountCouponLevelRelation.objects.get_or_create(defaults=relation_data, parent_id=instance1.id, child_id=query.id)
                    level_level_list = []
                    for i in range(4, level_range, -1):
                        level_level_list.append(i)
                        queryset = AliDiscountCouponLevel.objects.filter(id__in=queryset_list1, level__level__in=level_level_list)
                        for query in queryset:
                            query_level = query.level
                            if i == 4:
                                diacountcouponlevel_level_id = query_level.parent_id
                            elif i == 3:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            elif i == 2:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                elif query_level.level == 3:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            else:
                                if query_level.level == 4:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent.parent_id
                                elif query_level.level == 3:
                                    diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                elif query_level.level == 2:
                                    diacountcouponlevel_level_id = query_level.parent.parent_id
                                else:
                                    diacountcouponlevel_level_id = query_level.parent_id
                            instance1 = AliDiscountCouponLevel.objects.filter(level_id=diacountcouponlevel_level_id, activity_id=activity_id).first()
                            if not instance1:
                                instance1 = AliDiscountCouponLevel.objects.create(level_id=diacountcouponlevel_level_id, activity_id=activity_id, max_number=0)
                            queryset_list1.append(instance1.id)
                            relation_data = {
                                "parent_id": instance1.id,
                                "child_id": query.id
                            }
                            AliDiscountCouponLevelRelation.objects.get_or_create(defaults=relation_data, parent_id=instance1.id, child_id=query.id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '分配成功'}, status=status.HTTP_200_OK)
        elif instance.coupon_way == 4:
            if not data_array:
                return Response({'error': '缺少分配参数'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    for level_id in data_array:
                        if int(level_id) not in level_list:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                        diacountcouponlevel = AliDiscountCouponLevel.objects.filter(activity_id=activity_id, level_id=level_id).first()
                        if diacountcouponlevel:
                            diacountcouponlevel.is_auth = 1
                            diacountcouponlevel.save()
                        else:
                            diacountcouponlevel_data = {}
                            diacountcouponlevel_data['level_id'] = level_id
                            diacountcouponlevel_data['activity_id'] = activity_id
                            diacountcouponlevel_data['is_auth'] = 1
                            diacountcouponlevel, create = AliDiscountCouponLevel.objects.get_or_create(activity_id=activity_id, level_id=level_id, defaults=diacountcouponlevel_data)
                            level_level_list = []
                            queryset_list = []
                            queryset_list.append(diacountcouponlevel.id)
                            for i in range(4, level_range, -1):
                                level_level_list.append(i)
                                queryset = AliDiscountCouponLevel.objects.filter(id__in=queryset_list, level__level__in=level_level_list)
                                for query in queryset:
                                    query_level = query.level
                                    if i == 4:
                                        diacountcouponlevel_level_id = query_level.parent_id
                                    elif i == 3:
                                        if query_level.level == 4:
                                            diacountcouponlevel_level_id = query_level.parent.parent_id
                                        else:
                                            diacountcouponlevel_level_id = query_level.parent_id
                                    elif i == 2:
                                        if query_level.level == 4:
                                            diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                        elif query_level.level == 3:
                                            diacountcouponlevel_level_id = query_level.parent.parent_id
                                        else:
                                            diacountcouponlevel_level_id = query_level.parent_id
                                    else:
                                        if query_level.level == 4:
                                            diacountcouponlevel_level_id = query_level.parent.parent.parent.parent_id
                                        elif query_level.level == 3:
                                            diacountcouponlevel_level_id = query_level.parent.parent.parent_id
                                        elif query_level.level == 2:
                                            diacountcouponlevel_level_id = query_level.parent.parent_id
                                        else:
                                            diacountcouponlevel_level_id = query_level.parent_id
                                    instance1 = AliDiscountCouponLevel.objects.filter(level_id=diacountcouponlevel_level_id, activity_id=activity_id).first()
                                    if not instance1:
                                        instance1 = AliDiscountCouponLevel.objects.create(level_id=diacountcouponlevel_level_id, activity_id=activity_id, max_number=0)
                                    queryset_list.append(instance1.id)
                                    relation_data = {
                                        "parent_id": instance1.id,
                                        "child_id": query.id
                                    }
                                    AliDiscountCouponLevelRelation.objects.get_or_create(defaults=relation_data, parent_id=instance1.id, child_id=query.id)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '分配成功'}, status=status.HTTP_200_OK)
        elif instance.coupon_way == 7:
            if not data_array:
                return Response({'error': '缺少分配参数'}, status=status.HTTP_400_BAD_REQUEST)
            with transaction.atomic():
                # 创建事务保存点
                save_id = transaction.savepoint()
                try:
                    for level_id in data_array:
                        if int(level_id) not in level_list:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '存在无权限机构'}, status=status.HTTP_400_BAD_REQUEST)
                        diacountcouponlevel = AliDiscountCouponLevel.objects.filter(activity_id=activity_id, level_id=level_id).first()
                        if diacountcouponlevel:
                            diacountcouponlevel.is_auth = 1
                            diacountcouponlevel.save()
                        else:
                            diacountcouponlevel_data = {}
                            diacountcouponlevel_data['level_id'] = level_id
                            diacountcouponlevel_data['activity_id'] = activity_id
                            diacountcouponlevel_data['is_auth'] = 1
                            identify = random_str(randomlength=64)
                            if instance.drawdown_platform_id == 3:
                                common_url = f'https://qrcode.sutpay.com/business/coupon/?identify={identify}'
                            else:
                                common_url = f'https://api.sutpay.com/customer/coupon/?identify={identify}'
                            common_qrcode = f'youhuiquanyi/coupon/{identify}.png'
                            common_qrcode_url = make_qrcode2(identify, common_url, common_qrcode)
                            diacountcouponlevel_data['common_url'] = common_url
                            diacountcouponlevel_data['common_qrcode'] = common_qrcode
                            diacountcouponlevel_data['identify'] = identify
                            diacountcouponlevel, create = AliDiscountCouponLevel.objects.get_or_create(activity_id=activity_id, level_id=level_id, defaults=diacountcouponlevel_data)
                except Exception as e:
                    logger.error(e)
                    transaction.savepoint_rollback(save_id)
                    return Response({'error': '分配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
                transaction.savepoint_commit(save_id)
                return Response({'success': '分配成功'}, status=status.HTTP_200_OK)
        else:
            return Response({'error': '当前活动类型不允许分配'}, status=status.HTTP_400_BAD_REQUEST)

    def allocation_level(self, request):
        activity_id = self.request.query_params.get('activity_id', None)
        search = self.request.query_params.get('search', None)
        if not activity_id:
            return Response({'error': '请传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            activity = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            max_number__sum = activity.alidiscountcouponlevel_set.all().aggregate(Sum('max_number'))['max_number__sum']
            if max_number__sum:
                remain_number = activity.max_number - max_number__sum
            else:
                remain_number = activity.max_number
            can_remain_number = remain_number
        except:
            can_remain_number = 0
        try:
            if '_mutable' in self.request.data.__dict__:
                self.request.data.__dict__['_mutable'] = True
        except:
            pass
        self.request.data['can_remain_number'] = str(can_remain_number)
        level = activity.level
        if level.level == 0:
            queryset = Level.objects.all().order_by('level')
        elif level.level == 1:
            queryset = Level.objects.filter(prov_id=level.id).order_by('level')
        elif level.level == 2:
            queryset = Level.objects.filter(city_id=level.id).order_by('level')
        elif level.level == 3:
            queryset = Level.objects.filter(district_id=level.id).order_by('level')
        else:
            queryset = Level.objects.filter(branch_id=level.id).order_by('level')
        queryset = queryset.exclude(alidiscountcouponlevel__activity_id=activity_id)
        if search:
            queryset = queryset.filter(Q(name__contains=search) | Q(account__contains=search))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = LevelListSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = LevelListSerializer(queryset, many=True)
        return Response(serializer.data)

    def sync_use_merchant(self, request):
        alidiscountcoupon_id = self.request.query_params.get('alidiscountcoupon_id', None)
        if not alidiscountcoupon_id:
            return Response({'error': '请传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        activity = self.get_queryset().filter(id=alidiscountcoupon_id, coupon_channel=2).first()
        if not activity:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if activity.syn_status == 2:
            return Response({'error': '活动可用商户同步中'}, status=status.HTTP_400_BAD_REQUEST)
        syn_count = AliDiscountCoupon.objects.filter(syn_status=2).count()
        if syn_count > 10:
            return Response({'error': '同步可用商户的活动超过10个'}, status=status.HTTP_400_BAD_REQUEST)
        sync_activity_merchant.delay({'id': activity.id})
        return Response({'success': '同步成功'}, status=status.HTTP_200_OK)

    def bind_developer(self, request):
        user = self.request.iser
        activity_id = self.request.data.get('activity_id', None)
        developer_id = self.request.data.get('developer_id', None)
        product_no = self.request.data.get('product_no', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.coupon_way != 5:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            developer = User.objects.get(id=developer_id)
        except:
            return Response({'error': '无效开发者id'}, status=status.HTTP_400_BAD_REQUEST)
        if developer.is_developer != 1:
            return Response({'error': '关联用户尚未成为开发者'}, status=status.HTTP_400_BAD_REQUEST)
        if developer.is_active != 1:
            return Response({'error': '关联用户状态有误'}, status=status.HTTP_400_BAD_REQUEST)
        if developer.id == 65449:
            if not product_no:
                return Response({'error': '请上传商品id'}, status=status.HTTP_400_BAD_REQUEST)
            check_activity = AliDiscountCoupon.objects.filter(product_no=product_no)
            if check_activity:
                return Response({'error': '重复商品id'}, status=status.HTTP_400_BAD_REQUEST)
            instance.product_no = product_no
            instance.save()
        data = {}
        data['developer_id'] = developer_id
        data['alidiscountcoupon_id'] = activity_id
        data['create_user_id'] = user.id
        AliDiscountCouponAPIRelation.objects.get_or_create(defaults=data, developer_id=developer_id, alidiscountcoupon_id=activity_id)
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def unbind_developer(self, request):
        id = self.request.data.get('id', None)
        if not id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            AliDiscountCouponAPIRelation.objects.filter(id=id).delete()
            return Response({'error': '操作成功'}, status=status.HTTP_200_OK)
        except:
            return Response({'error': '操作失败'}, status=status.HTTP_400_BAD_REQUEST)

    def sync_wyh_data(self, request):
        user = self.request.iser
        activity_id = self.request.data.get('activity_id', None)
        try:
            instance = self.get_queryset().get(id=activity_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.coupon_way not in [1, 4, 2, 7]:
            return Response({'error': '仅限员工派券活动'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.coupon_channel not in [2]:
            return Response({'error': '仅限微信代金券活动'}, status=status.HTTP_400_BAD_REQUEST)
        if instance.distribution_platform_id not in [5, 6]:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        check_record = AliDiscountCouponSyncWYHRecord.objects.filter(sync_status__in=[1, 2], alidiscountcoupon_id=instance.id)
        if check_record:
            return Response({'error': '活动已在队列中,请勿重复提交'}, status=status.HTTP_400_BAD_REQUEST)
        check_record = AliDiscountCouponSyncWYHRecord.objects.filter(sync_status=1).first()
        if check_record:
            AliDiscountCouponSyncWYHRecord.objects.create(
                alidiscountcoupon_id=instance.id,
                create_user_id=user.id,
                sync_status=2,
            )
        else:
            record = AliDiscountCouponSyncWYHRecord.objects.create(
                alidiscountcoupon_id=instance.id,
                create_user_id=user.id,
                sync_status=1,
            )
            sync_activity_wyh_data.delay({'record_id': record.id})
        return Response({'success': '提交成功,请等待处理'}, status=status.HTTP_200_OK)

    def export_activity(self, request):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level_id', None)
        coupon_status = self.request.query_params.get('coupon_status', None)
        coupon_channel = self.request.query_params.get('coupon_channel', None)
        distribution_platform_id = self.request.query_params.get('distribution_platform_id', None)
        publish_time_begin = self.request.query_params.get('publish_time_begin', None)
        publish_time_end = self.request.query_params.get('publish_time_end', None)
        user_id = self.request.query_params.get('user_id', None)
        search = self.request.query_params.get('search', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE id!=0'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        if search:
            condition = condition + f' AND (activity_name LIKE "%{search}%" OR template_id LIKE "%{search}%" )'
        if publish_time_begin:
            condition = condition + f' AND publish_time_begin >= "{publish_time_begin + " 00:00:00"}"'
        if publish_time_end:
            condition = condition + f' AND publish_time_end <= "{publish_time_end + " 23:59:59"}"'
        if coupon_status:
            condition = condition + f' AND coupon_status in ({coupon_status})'
        if coupon_channel:
            condition = condition + f' AND coupon_channel in ({coupon_channel})'
        if distribution_platform_id:
            condition = condition + f' AND distribution_platform_id in ({distribution_platform_id})'
        if user_id:
            condition = condition + f' AND user_id={user_id}'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT e.*,f.platform_name FROM (SELECT c.*,d.name,mchid FROM (SELECT a.*,b.prov_name,city_name,district_name,branch_name FROM (SELECT id,template_id,activity_name,level_id,coupon_status,coupon_way,coupon_type,distribution_platform_id,floor_amount,DATE_FORMAT(publish_start_time,'%Y-%m-%d %H:%i:%S') AS publish_start_time,DATE_FORMAT(publish_end_time,'%Y-%m-%d %H:%i:%S') AS publish_end_time,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,platform_id,amount,send_count,remain_number,max_number,use_count,use_amount FROM tb_ali_discount_coupon {condition})AS a LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT id,name,mchid FROM tb_channel)AS d ON c.platform_id=d.id)AS e LEFT JOIN (SELECT id,platform_name FROM tb_ali_discount_coupon_distribution_platform)AS f ON e.distribution_platform_id=f.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT e.*,f.platform_name FROM (SELECT c.*,d.name,mchid FROM (SELECT a.*,b.prov_name,city_name,district_name,branch_name FROM (SELECT id,template_id,activity_name,level_id,coupon_status,coupon_way,coupon_type,distribution_platform_id,floor_amount,DATE_FORMAT(publish_start_time,'%Y-%m-%d %H:%i:%S') AS publish_start_time,DATE_FORMAT(publish_end_time,'%Y-%m-%d %H:%i:%S') AS publish_end_time,DATE_FORMAT(create_time,'%Y-%m-%d %H:%i:%S') AS create_time,platform_id,amount,send_count,remain_number,max_number,use_count,use_amount FROM tb_ali_discount_coupon)AS a LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT id,name,mchid FROM tb_channel)AS d ON c.platform_id=d.id)AS e LEFT JOIN (SELECT id,platform_name FROM tb_ali_discount_coupon_distribution_platform)AS f ON e.distribution_platform_id=f.id;
            '''
            cursor.execute(sql)
        ziduan = ['活动id', '微信代金券批次', '活动名称', '活动归属机构(省)', '活动归属机构(市)', '活动归属机构(区)', '派发方式',
                  '活动状态', '派发平台', '优惠规则', '活动时间(起)', '活动时间(止)', '活动创建时间', '配券平台', '优惠券面额',
                  '已派发', '剩余', '总共', '已核销']
        cols = ['id', 'template_id', 'activity_name', 'prov_name', 'city_name', 'district_name',
                'coupon_way', 'coupon_status', 'platform_name', 'floor_amount', 'publish_start_time', 'publish_end_time',
                'create_time', 'mchid', 'amount', 'send_count', 'remain_number', 'max_number', 'use_count']
        response = StreamingHttpResponse(self.get_activity_merchant_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('订单列表.csv'))
        return response

    def get_activity_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        COUPONS_STATUS_ENUM = {
            "1": '进行中',
            "2": '已结束',
            "3": '未开始',
            "4": '已暂停'
        }
        COUPON_WAY_ENUM = {
            "1": '员工派券(固定)',
            "2": '公开派券',
            "3": '限时活动',
            "4": '员工派券(共享)',
            "5": 'API派券',
            "6": '定制活动',
            "7": '公开派券(多码)',
            "8": '公开派券(手机银行)'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'coupon_status':
                    tmp_str += '"%s",' % (COUPONS_STATUS_ENUM[row[col]])
                elif col == 'coupon_way':
                    tmp_str += '"%s",' % (COUPON_WAY_ENUM[row[col]])
                elif col == 'coupon_way':
                    tmp_str += '"%s",' % (COUPON_WAY_ENUM[row[col]])
                elif col in ['send_count', 'remain_number', 'max_number', 'use_count']:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else 0)
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def add_coupon_goods(self, request):
        user = self.request.iser
        goods_id_array = self.request.data.get('goods_id_array', None)
        alidiscountcoupon_id = self.request.data.get('alidiscountcoupon_id', None)
        if not all([goods_id_array, alidiscountcoupon_id]):
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=alidiscountcoupon_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if type(goods_id_array) != list:
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                for goods_id in goods_id_array:
                    available_data = {}
                    available_data['goods_id'] = goods_id
                    available_data['alidiscountcoupon_id'] = alidiscountcoupon_id
                    AliDiscountCouponGoodsAvailable.objects.get_or_create(defaults=available_data, goods_id=goods_id, alidiscountcoupon_id=alidiscountcoupon_id)
                transaction.savepoint_commit(save_id)
                return Response({'success': '绑定成功'}, status=status.HTTP_200_OK)
            except:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '绑定失败'}, status=status.HTTP_400_BAD_REQUEST)

    def coupon_goods(self, request):
        user = self.request.iser
        add_goods_id_array = self.request.data.get('add_goods_id_array', None)
        del_goods_id_array = self.request.data.get('del_goods_id_array', None)
        alidiscountcoupon_id = self.request.data.get('alidiscountcoupon_id', None)
        if not alidiscountcoupon_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            instance = self.get_queryset().get(id=alidiscountcoupon_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        if type(add_goods_id_array) != list:
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        if type(del_goods_id_array) != list:
            return Response({'error': '参数类型有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                for goods_id in add_goods_id_array:
                    available_data = {}
                    available_data['goods_id'] = goods_id
                    available_data['alidiscountcoupon_id'] = alidiscountcoupon_id
                    AliDiscountCouponGoodsAvailable.objects.get_or_create(defaults=available_data, goods_id=goods_id, alidiscountcoupon_id=alidiscountcoupon_id)
                AliDiscountCouponGoodsAvailable.objects.filter(goods_id__in=del_goods_id_array, alidiscountcoupon_id=alidiscountcoupon_id).delete()
                transaction.savepoint_commit(save_id)
                return Response({'success': '解绑成功'}, status=status.HTTP_200_OK)
            except:
                transaction.savepoint_rollback(save_id)
                return Response({'error': '解绑失败'}, status=status.HTTP_400_BAD_REQUEST)

    def submit_ysh(self, request):
        user = self.request.iser
        sourceDistCode_id = self.request.data.get('sourceDistCode_id', None)
        showDistCode = self.request.data.get('showDistCode', None)
        usageType = self.request.data.get('usageType', None)
        alidiscountcoupon_id = self.request.data.get('alidiscountcoupon_id', None)
        area_array = self.request.data.get('area_array', None)
        environment = self.request.data.get('environment', '1')
        contract_id = self.request.data.get('contract_id', '1')
        if not alidiscountcoupon_id:
            return Response({'error': '请上传活动id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            alidiscountcoupon = self.get_queryset().get(id=alidiscountcoupon_id)
        except:
            return Response({'error': '无效活动id'}, status=status.HTTP_400_BAD_REQUEST)
        check_ysh_alidiscountcoupon = YSHAliDiscountCoupon.objects.filter(alidiscountcoupon_id=alidiscountcoupon.id)
        if check_ysh_alidiscountcoupon:
            return Response({'error': '不可重复提交'}, status=status.HTTP_400_BAD_REQUEST)
        if alidiscountcoupon.coupon_way != 5:
            return Response({'error': '活动派发方式有误'}, status=status.HTTP_400_BAD_REQUEST)
        if alidiscountcoupon.distribution_platform_id != 7:
            return Response({'error': '活动派发方式不是邮生活'}, status=status.HTTP_400_BAD_REQUEST)
        if not sourceDistCode_id:
            return Response({'error': '请上传卡券来源的行政区划码'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            sourceDistCode = YSHAreaCode.objects.get(id=sourceDistCode_id)
        except:
            return Response({'error': '无效行政编码id'}, status=status.HTTP_400_BAD_REQUEST)
        if not usageType:
            return Response({'error': '请上传卡券使用类型'}, status=status.HTTP_400_BAD_REQUEST)
        if str(usageType) not in ['1', '2']:
            return Response({'error': '卡券使用类型参数有误'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            contract = YSHContract.objects.get(id=contract_id)
        except:
            return Response({'error': '无效合同id'}, status=status.HTTP_400_BAD_REQUEST)
        showDistCode_list = []
        showDistCode_str = ''
        if showDistCode:
            if not isinstance(showDistCode, list):
                return Response({'error': '商品地区参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            for showDistCode_id in showDistCode:
                showDist = YSHAreaCode.objects.filter(id=showDistCode_id).first()
                if showDist:
                    showDistCode_list.append(showDist.code)
                    showDistCode_str += f'{showDist.id},'
        area_list = []
        area_str = ''
        if area_array:
            if not isinstance(area_array, list):
                return Response({'error': '商品地区参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
            for area_id in area_array:
                area = YSHAreaCode.objects.filter(id=area_id).first()
                if area:
                    area_list.append({
                        "province": area.prov_name if area.prov_name else "",
                        "city": area.city_name if area.city_name else "",
                        "district": area.district_name if area.district_name else "",
                        "adcode": area.code
                    })
                    area_str += f'{area.id},'
        equityId = f'{alidiscountcoupon.template_id}_WYH_{sourceDistCode.code}'
        name = alidiscountcoupon.activity_name
        type = 'VOUCHER'
        startedAt = alidiscountcoupon.publish_start_time.strftime('%Y-%m-%dT%H:%M:%S+08:00')
        endedAt = alidiscountcoupon.publish_end_time.strftime('%Y-%m-%dT%H:%M:%S+08:00')
        logo = 'https://ea.sutpay.com/favicon.ico'
        desc = alidiscountcoupon.activity_description
        source = 'WYH'
        verifyChannel = YSHAliDiscountCoupon.VERIFY_CHANNEL_ENUM[alidiscountcoupon.coupon_channel]
        inventory = alidiscountcoupon.remain_number
        totalInventory = alidiscountcoupon.max_number
        couponAmount = int(alidiscountcoupon.amount * 100)
        transactionMinimum = int(alidiscountcoupon.transaction_minimum * 100)
        costAmount = int(Decimal(str(couponAmount*(Decimal('1')+Decimal(str(contract.taxRate/100))))).quantize(Decimal('0')))
        maxCouponsPerUser = alidiscountcoupon.max_number_by_user
        identify = random_str(32)
        mchUrl = f'https://yshmer.sutpay.com/#/?identify={identify}'
        timestamp = str(int(time.time()))
        method = 'saveEquityInfo'
        if str(environment) == '2':
            url = 'http://211.156.216.240:8086/zxyw_uat'
            accessKey = 'f05dba56b4ce41939cd4737d2793752d'
            secretKey = 'Km9t1dW5QZT/hL3ohTIqcoGW2Ok='
        else:
            url = 'http://211.156.195.141:8086/zxyw_sc'
            accessKey = '6a69bf6dbf104e43966204b9fb533747'
            secretKey = 'CAz0q5SXM+DyYxz73yBLIHgu3vM='
        body = {}
        paramJson = {}
        voucher = {}
        paramJson['equityId'] = equityId
        paramJson['name'] = name
        paramJson['type'] = type
        voucher['name'] = name
        voucher['couponAmount'] = couponAmount
        voucher['transactionMinimum'] = transactionMinimum
        voucher['maxCouponsPerUser'] = maxCouponsPerUser
        voucher['mchUrl'] = mchUrl
        voucher['costAmount'] = costAmount
        voucher['supplierCode'] = contract.supplierCode
        voucher['supplierName'] = contract.supplierName
        voucher['contractCode'] = contract.contractCode
        voucher['contractName'] = contract.contractName
        voucher['taxRate'] = float(contract.taxRate/100)
        paramJson['voucher'] = voucher
        paramJson['startedAt'] = startedAt
        paramJson['area'] = area_list
        paramJson['endedAt'] = endedAt
        paramJson['logo'] = {"url": logo}
        paramJson['desc'] = desc
        paramJson['source'] = source
        paramJson['inventory'] = inventory
        paramJson['totalInventory'] = totalInventory
        paramJson['sourceDistCode'] = sourceDistCode.code
        paramJson['showDistCode'] = showDistCode_list
        paramJson['usageType'] = YSHAliDiscountCoupon.VERIFY_CHANNEL_ENUM[int(usageType)]
        paramJson['verifyChannel'] = verifyChannel
        body['paramJson'] = paramJson
        headers = {
            '_api_access_key': accessKey,
            '_api_name': method,
            '_api_timestamp': str(timestamp),
            '_api_version': '1.0.0'
        }
        sign = get_sign_HMACSHA1(headers, secretKey)
        headers['_api_signature'] = sign
        headers['Content-Type'] = 'application/json'
        headers['User-Agent'] = 'PostmanRuntime/7.28.2'
        response = requests.post(url=url, headers=headers, data=json.dumps(body))
        result = response.json()
        logger.info(str(result))
        data = json.loads(result['body'])
        if data['retCode'] == '100001':
            ysh_alidiscountcoupon_data = {}
            ysh_alidiscountcoupon_data['alidiscountcoupon_id'] = alidiscountcoupon.id
            ysh_alidiscountcoupon_data['equityId'] = equityId
            ysh_alidiscountcoupon_data['name'] = name
            ysh_alidiscountcoupon_data['type'] = 1
            ysh_alidiscountcoupon_data['startedAt'] = alidiscountcoupon.publish_start_time
            ysh_alidiscountcoupon_data['endedAt'] = alidiscountcoupon.publish_end_time
            ysh_alidiscountcoupon_data['inventory'] = inventory
            ysh_alidiscountcoupon_data['totalInventory'] = totalInventory
            ysh_alidiscountcoupon_data['couponAmount'] = couponAmount
            ysh_alidiscountcoupon_data['transactionMinimum'] = transactionMinimum
            ysh_alidiscountcoupon_data['mchUrl'] = mchUrl
            ysh_alidiscountcoupon_data['maxCouponsPerUser'] = maxCouponsPerUser
            ysh_alidiscountcoupon_data['sourceDistCode_id'] = sourceDistCode.id
            ysh_alidiscountcoupon_data['showDistCode'] = showDistCode_str[:-1]
            ysh_alidiscountcoupon_data['usageType'] = usageType
            ysh_alidiscountcoupon_data['verifyChannel'] = alidiscountcoupon.coupon_channel
            ysh_alidiscountcoupon_data['serialNo'] = data['serialNo']
            ysh_alidiscountcoupon_data['user_id'] = user.id
            ysh_alidiscountcoupon_data['create_time'] = datetime.datetime.now()
            ysh_alidiscountcoupon_data['identify'] = identify
            ysh_alidiscountcoupon_data['area'] = area_str[:-1]
            ysh_alidiscountcoupon_data['environment'] = environment
            ysh_alidiscountcoupon_data['contract_id'] = contract.id
            ysh_alidiscountcoupon_data['costAmount'] = costAmount
            YSHAliDiscountCoupon.objects.get_or_create(defaults=ysh_alidiscountcoupon_data, alidiscountcoupon_id=alidiscountcoupon.id)
            return Response({'success': '操作成功'}, status=status.HTTP_200_OK)
        else:
            return Response({'error': '操作失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)


class AliDiscountCouponLevelModelViewSet(ModelViewSet):

    pagination_class = MyPage
    search_fields = ('level__name', )
    filter_class = AliDiscountCouponLevelFilter
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        sort = self.request.query_params.get('sort', '0')
        # activity_id = self.request.query_params.get('activity_id', None)
        # if activity_id:
        #     try:
        #         activity = AliDiscountCoupon.objects.get(id=activity_id)
        #         max_number__sum = activity.alidiscountcouponlevel_set.all().aggregate(Sum('max_number'))['max_number__sum']
        #         if max_number__sum:
        #             remain_number = activity.max_number - max_number__sum
        #         else:
        #             remain_number = activity.max_number
        #         if '_mutable' in self.request.data.__dict__:
        #             self.request.data.__dict__['_mutable'] = True
        #         self.request.data['can_remain_number'] = str(remain_number)
        #     except:
        #         pass
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = AliDiscountCouponLevel.objects.all()
        elif level.level == 1:
            queryset = AliDiscountCouponLevel.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = AliDiscountCouponLevel.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = AliDiscountCouponLevel.objects.filter(level__district_id=level.id)
        else:
            queryset = AliDiscountCouponLevel.objects.filter(level__branch_id=level.id)
        if sort == '0':
            queryset = queryset.order_by('max_number', 'id')
        elif sort == '1':
            queryset = queryset.order_by('-max_number', 'id')
        elif sort == '2':
            queryset = queryset.order_by('take_number', 'id')
        elif sort == '3':
            queryset = queryset.order_by('-take_number', 'id')
        elif sort == '4':
            queryset = queryset.order_by('remain_number', 'id')
        elif sort == '5':
            queryset = queryset.order_by('-remain_number', 'id')
        elif sort == '6':
            queryset = queryset.order_by(F('take_number') - F('receive_number'), 'id')
        elif sort == '7':
            queryset = queryset.order_by(-(F('take_number') - F('receive_number')), 'id')
        elif sort == '8':
            queryset = queryset.order_by(F('receive_number') - F('use_number'), 'id')
        elif sort == '9':
            queryset = queryset.order_by(-(F('receive_number') - F('use_number')), 'id')
        elif sort == '10':
            queryset = queryset.order_by('use_number', 'id')
        elif sort == '11':
            queryset = queryset.order_by('-use_number', 'id')
        else:
            queryset = queryset.order_by('level__level', 'id')
        return queryset

    def get_serializer_class(self):
        if self.action == 'list':
            return AliDiscountCouponLevelListModelSerializer
        else:
            return AliDiscountCouponLevelRetrieveModelSerializer

    def up_file(self, request):
        my_file = self.request.FILES.get('my_file', None)

    def export_couponlevel(self, request):
        activity_id = self.request.query_params.get('activity_id', None)
        search = self.request.query_params.get('search', None)
        user = self.request.iser
        if not search:
            if user.level.level == 0:
                condition = ''
            elif user.level.level == 1:
                condition = f'WHERE prov_id={user.id}'
            elif user.level.level == 2:
                condition = f'WHERE city_id={user.id}'
            elif user.level.level == 3:
                condition = f'WHERE district_id={user.id}'
            else:
                condition = f'WHERE branch_id={user.id}'
        else:
            if user.level.level == 0:
                condition = f'WHERE name LIKE "%{search}%"'
            elif user.level.level == 1:
                condition = f'WHERE prov_id={user.id} AND name LIKE "%{search}%"'
            elif user.level.level == 2:
                condition = f'WHERE city_id={user.id} AND name LIKE "%{search}%"'
            elif user.level.level == 3:
                condition = f'WHERE district_id={user.id} AND name LIKE "%{search}%"'
            else:
                condition = f'WHERE branch_id={user.id} AND name LIKE "%{search}%"'
        if not activity_id:
            condition1 = ''
        else:
            condition1 = f'AND activity_id="{activity_id}"'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        sql = f'''
        SELECT c.*,d.activity_name FROM (SELECT a.*,b.name,account,prov_name,city_name,district_name,branch_name FROM (SELECT id,activity_id,max_number,take_number,remain_number,receive_number,use_number,level_id,(take_number-receive_number)AS unclaimed_number,(receive_number-use_number)AS wait_number FROM tb_ali_discount_coupon_level WHERE max_number!=0 AND level_id IN (SELECT id FROM tb_u_level {condition}) {condition1})AS a LEFT JOIN (SELECT id,name,account,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS b ON a.level_id=b.id)AS c LEFT JOIN (SELECT id,activity_name FROM tb_ali_discount_coupon)AS d ON c.activity_id=d.id;
        '''
        cursor.execute(sql)
        ziduan = ['id', '活动名称', '机构名称', '机构号', '省', '市', '区县', '网点', '总额度', '已派发额度', '剩余额度', '待领取', '待核销', '已核销']
        cols = ['id', 'activity_name', 'name', 'account', 'prov_name', 'city_name', 'district_name', 'branch_name', 'max_number', 'take_number', 'remain_number', 'unclaimed_number',
                'wait_number', 'use_number']
        response = StreamingHttpResponse(self.get_couponlevel_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('支付宝代金券机构领用汇总.csv'))
        return response

    def get_couponlevel_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                # if col == 'unclaimed_number':
                #     tmp_str += '"%s",' % (row['take_number']-row['receive_number'])
                # elif col == 'wait_number':
                #     tmp_str += '"%s",' % (row['receive_number']-row['use_number'])
                if col in ['max_number', 'take_number', 'remain_number', 'unclaimed_number', 'wait_number', 'use_number']:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else 0)
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def batch_update_max_number(self, request):
        data_array = self.request.data.get('data_array', None)
        if not data_array:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not isinstance(data_array, list):
            return Response({'error': '参数格式有误'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()

            # 暴力回滚
            try:
                for data in data_array:
                    instance = AliDiscountCouponLevel.objects.get(id=data['id'])

                    count = -int(data['count'])
                    if count < 0 and instance.remain_number < abs(count):
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': f'{instance.id}剩余数量不足扣减'}, status=status.HTTP_400_BAD_REQUEST)
                    activity = instance.activity
                    instance.max_number = instance.max_number + count
                    instance.remain_number = instance.remain_number + count
                    instance.p_max_number = instance.p_max_number + count
                    instance.p_remain_number = instance.p_remain_number + count
                    instance.save()
                    activity.max_number += count
                    activity.remain_number += count
                    activity.save()
                    relation_set = instance.child_set.all()
                    for relation in relation_set:
                        parent = relation.parent
                        parent.p_max_number += count
                        parent.p_remain_number += count
                        parent.save()
            except Exception as e:
                logger.error(e)
                # 事务回滚
                transaction.savepoint_rollback(save_id)
                return Response({'error': '修改失败'}, status=status.HTTP_400_BAD_REQUEST)
        transaction.savepoint_commit(save_id)
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        max_number = self.request.data.get('max_number', None)
        try:
            max_number = int(max_number)
        except:
            return Response({'error': '请输入整数额度'}, status=status.HTTP_400_BAD_REQUEST)
        activity = instance.activity
        if activity.coupon_way != 1:
            return Response({'error': '仅员工派券活动可调整派发额度'}, status=status.HTTP_400_BAD_REQUEST)
        # if instance.max_number <= 0:
        #     return Response({'error': '机构活动额度不足'}, status=status.HTTP_400_BAD_REQUEST)
        instance_id = instance.id
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()
            try:
                while True:
                    instance = AliDiscountCouponLevel.objects.get(id=instance_id)
                    count = max_number - instance.max_number
                    if count > 0:
                        max_number__sum = activity.alidiscountcouponlevel_set.all().aggregate(Sum('max_number'))['max_number__sum']
                        if max_number__sum:
                            remain_number = activity.max_number - max_number__sum
                        else:
                            remain_number = activity.max_number
                        if remain_number < count:
                            transaction.savepoint_rollback(save_id)
                            return Response({'error': '活动额度不足'}, status=status.HTTP_400_BAD_REQUEST)
                    else:
                        if instance.remain_number < -count:
                            return Response({'error': '机构活动额度不足'}, status=status.HTTP_400_BAD_REQUEST)
                    origin_remain_number = instance.remain_number
                    origin_max_number = instance.max_number
                    origin_p_remain_number = instance.p_remain_number
                    origin_p_max_number = instance.p_max_number
                    new_remain_number = origin_remain_number + count
                    new_max_number = origin_max_number + count
                    new_p_remain_number = origin_p_remain_number + count
                    new_p_max_number = origin_p_max_number + count
                    result = AliDiscountCouponLevel.objects.filter(id=instance_id, remain_number=origin_remain_number).update(
                        max_number=new_max_number,
                        remain_number=new_remain_number,
                        p_max_number=new_p_max_number,
                        p_remain_number=new_p_remain_number
                    )
                    if result == 0:
                        continue
                    break
                relation_set = instance.child_set.all()
                for relation in relation_set:
                    parent = relation.parent
                    parent.p_max_number += count
                    parent.p_remain_number += count
                    parent.save()
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '调配失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '调配成功'}, status=status.HTTP_200_OK)

    def transfer_max_number(self, request):
        count = self.request.data.get('count', None)
        in_id = self.request.data.get('in_id', None)
        out_id = self.request.data.get('out_id', None)
        try:
            count = int(count)
        except:
            return Response({'error': '请输入整数额度'}, status=status.HTTP_400_BAD_REQUEST)
        if count <= 0:
            return Response({'error': '请输入正整数额度'}, status=status.HTTP_400_BAD_REQUEST)
        queryset = self.get_queryset()
        try:
            in_instance = queryset.get(id=in_id)
        except:
            return Response({'error': '无效转入id'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            out_instance = queryset.get(id=out_id)
        except:
            return Response({'error': '无效转出id'}, status=status.HTTP_400_BAD_REQUEST)
        if in_instance.activity_id != out_instance.activity_id:
            return Response({'error': '不同活动之间不允许转让'}, status=status.HTTP_400_BAD_REQUEST)
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                while True:
                    in_instance = queryset.get(id=in_id)
                    out_instance = queryset.get(id=out_id)
                    if out_instance.remain_number < count:
                        transaction.savepoint_rollback(save_id)
                        return Response({'error': '转出机构额度不足'}, status=status.HTTP_400_BAD_REQUEST)
                    in_origin_remain_number = in_instance.remain_number
                    in_origin_max_number = in_instance.max_number
                    in_origin_p_remain_number = in_instance.p_remain_number
                    in_origin_p_max_number = in_instance.p_max_number
                    in_new_remain_number = in_origin_remain_number + count
                    in_new_max_number = in_origin_max_number + count
                    in_new_p_remain_number = in_origin_p_remain_number + count
                    in_new_p_max_number = in_origin_p_max_number + count
                    in_result = AliDiscountCouponLevel.objects.filter(id=in_id, remain_number=in_origin_remain_number).update(
                        max_number=in_new_max_number,
                        remain_number=in_new_remain_number,
                        p_max_number=in_new_p_max_number,
                        p_remain_number=in_new_p_remain_number
                    )
                    out_origin_remain_number = out_instance.remain_number
                    out_origin_max_number = out_instance.max_number
                    out_origin_p_remain_number = out_instance.p_remain_number
                    out_origin_p_max_number = out_instance.p_max_number
                    out_new_remain_number = out_origin_remain_number - count
                    out_new_max_number = out_origin_max_number - count
                    out_new_p_remain_number = out_origin_p_remain_number - count
                    out_new_p_max_number = out_origin_p_max_number - count
                    out_result = AliDiscountCouponLevel.objects.filter(id=out_id, remain_number=out_origin_remain_number).update(
                        max_number=out_new_max_number,
                        remain_number=out_new_remain_number,
                        p_max_number=out_new_p_max_number,
                        p_remain_number=out_new_p_remain_number
                    )
                    if in_result == 0 or out_result == 0:
                        continue
                    break
                in_relation_set = in_instance.child_set.all()
                for relation in in_relation_set:
                    parent = relation.parent
                    parent.p_max_number += count
                    parent.p_remain_number += count
                    parent.save()
                out_relation_set = out_instance.child_set.all()
                for relation in out_relation_set:
                    parent = relation.parent
                    parent.p_max_number -= count
                    parent.p_remain_number -= count
                    parent.save()
            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return Response({'error': '转让失败,请联系管理员'}, status=status.HTTP_400_BAD_REQUEST)
            transaction.savepoint_commit(save_id)
            return Response({'success': '转让成功'}, status=status.HTTP_200_OK)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.p_take_number != 0:
            return Response({'error': '已派发额度,不可删除'}, status=status.HTTP_400_BAD_REQUEST)
        activity = instance.activity
        if activity.coupon_way in [1, 2, 3]:
            relation_set = instance.child_set.all()
            for relation in relation_set:
                parent = relation.parent
                parent.p_max_number -= instance.max_number
                parent.p_remain_number -= instance.p_remain_number
                parent.save()
                if parent.p_max_number == Decimal(0):
                    parent.delete()
            relation_set = instance.parent_set.all()
            for relation in relation_set:
                relation.delete()
                child = relation.child
                child.delete()
        instance.delete()
        return Response({'success': '撤销成功'}, status=status.HTTP_200_OK)

    def alidiscountcouponlevel_tree(self, requset):
        activity_id = self.request.query_params.get('activity_id', None)
        if not activity_id:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        instance = self.get_queryset().filter(activity_id=activity_id).order_by('level__level').first()
        if not instance:
            return Response({}, status=status.HTTP_200_OK)
        serializer = AliDiscountCouponLevelTreeModelSerializer(instance)
        return Response(serializer.data, status=status.HTTP_200_OK)


class MerchantBillModelViewSet(ModelViewSet):

    pagination_class = MyPage
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('merchant__name', 'merchant__wyfMerchantID')
    filter_class = MerchantBillFilter

    def get_queryset(self):
        user = self.request.iser
        level = user.level
        level_id = self.request.query_params.get('level', None)
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            queryset = MerchantBill.objects.all()
        elif level.level == 1:
            queryset = MerchantBill.objects.filter(level__prov_id=level.id)
        elif level.level == 2:
            queryset = MerchantBill.objects.filter(level__city_id=level.id)
        elif level.level == 3:
            queryset = MerchantBill.objects.filter(level__district_id=level.id)
        else:
            queryset = MerchantBill.objects.filter(level__branch_id=level.id)
        return queryset.order_by('-receipts_time', 'id')

    def get_serializer_class(self):
        if self.action == 'list':
            return MerchantBillListModelSerializer
        else:
            return MerchantBillRetrieveModelSerializer

    def export_merchant_bill(self, request):
        user = self.request.iser
        receipts_time_end = self.request.query_params.get('receipts_time_end', None)
        receipts_time_begin = self.request.query_params.get('receipts_time_begin', None)
        settlement_time_end = self.request.query_params.get('settlement_time_end', None)
        settlement_time_begin = self.request.query_params.get('settlement_time_begin', None)
        payable_amount_min = self.request.query_params.get('payable_amount_min', None)
        payable_amount_max = self.request.query_params.get('payable_amount_max', None)
        level_id = self.request.query_params.get('level', None)
        bill_state = self.request.query_params.get('bill_state', None)
        search = self.request.query_params.get('search', None)
        bill_type = self.request.query_params.get('bill_type', None)
        channel_id = self.request.query_params.get('channel_id', None)
        level = user.level
        if level_id:
            try:
                level_list = get_level_list(level)
                level_id = int(level_id)
                if level_id in level_list:
                    level = Level.objects.filter(id=level_id).first()
            except:
                pass
        if level.level == 0:
            condition = 'WHERE id!=0'
        elif level.level == 1:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE prov_id={level.id})'
        elif level.level == 2:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE city_id={level.id})'
        elif level.level == 3:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE district_id={level.id})'
        else:
            condition = f'WHERE level_id IN (SELECT id FROM tb_u_level WHERE branch_id={level.id})'
        if search:
            condition = condition + f' AND (merchant_id IN (SELECT id FROM tb_merchant WHERE name LIKE "%{search}%" OR short_name LIKE "%{search}%" OR wyfMerchantID LIKE "%{search}%"))'
        if bill_state:
            condition = condition + f' AND bill_state in ({bill_state})'
        if bill_type:
            condition = condition + f' AND bill_type in ({bill_type})'
        if channel_id:
            condition = condition + f' AND channel_id in ({channel_id})'
        if receipts_time_begin:
            condition = condition + f' AND receipts_time >= "{receipts_time_begin + " 00:00:00"}"'
        if receipts_time_end:
            condition = condition + f' AND receipts_time <= "{receipts_time_end + " 23:59:59"}"'
        if settlement_time_begin:
            condition = condition + f' AND settlement_time >= "{settlement_time_begin + " 00:00:00"}"'
        if settlement_time_end:
            condition = condition + f' AND settlement_time <= "{settlement_time_end + " 23:59:59"}"'
        if payable_amount_min:
            condition = condition + f' AND payable_amount >= "{payable_amount_min}"'
        if payable_amount_max:
            condition = condition + f' AND payable_amount <= "{payable_amount_max}"'
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        try:
            sql = f'''
            SELECT e.*,f.channel_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.name,short_name,wyfMerchantID FROM (SELECT id,merchant_id,DATE_FORMAT(receipts_time,'%Y-%m-%d')AS receipts_time,DATE_FORMAT(settlement_time,'%Y-%m-%d %H:%i:%S')AS settlement_time,payable_amount,bill_state,account_bank,account_name,account_number,settlement_amount,level_id,channel_id,other_amount,other_commission,other_settlement_amount FROM tb_merchant_bill {condition})AS a LEFT JOIN(SELECT id,name,short_name,wyfMerchantID FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id,name AS channel_name FROM tb_channel)AS f ON e.channel_id=f.id;
            '''
            cursor.execute(sql)
        except:
            sql = f'''
            SELECT e.*,f.channel_name FROM (SELECT c.*,d.city_name,district_name,branch_name FROM (SELECT a.*,b.name,short_name,wyfMerchantID FROM (SELECT id,merchant_id,DATE_FORMAT(receipts_time,'%Y-%m-%d')AS receipts_time,DATE_FORMAT(settlement_time,'%Y-%m-%d %H:%i:%S')AS settlement_time,payable_amount,bill_state,account_bank,account_name,account_number,settlement_amount,level_id,channel_id,other_amount,other_commission,other_settlement_amount FROM tb_merchant_bill)AS a LEFT JOIN(SELECT id,name,short_name,wyfMerchantID FROM tb_merchant)AS b ON a.merchant_id=b.id)AS c LEFT JOIN (SELECT id,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id)AS e LEFT JOIN (SELECT id,name AS channel_name FROM tb_channel)AS f ON e.channel_id=f.id;
            '''
            cursor.execute(sql)
        ziduan = ['结算ID', '商户全称', '商户简称', '微邮付商户号', '清分日期', '结算时间', '清分金额', '结算金额',
                  '结算状态', '归属市公司', '归属区县', '归属网点', '结算通道', '结算户名', '结算卡号', '微邮付交易金额',
                  '微邮付交易手续费', '微邮付结算金额']
        cols = ['id', 'name', 'short_name', 'wyfMerchantID', 'receipts_time', 'settlement_time', 'payable_amount', 'settlement_amount',
                'bill_state', 'city_name', 'district_name', 'branch_name', 'channel_name', 'account_name', 'account_number', 'other_amount',
                'other_commission', 'other_settlement_amount']
        response = StreamingHttpResponse(self.get_merchant_bill_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('结算单信息.csv'))
        return response

    def get_merchant_bill_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        STATUS_ENUM = {
            1: '待结算',
            2: '结算中',
            3: '已结算',
            4: '已撤销',
            5: '结算失败'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'bill_state':
                    tmp_str += '"%s",' % (STATUS_ENUM[row[col]])
                elif col in ['other_commission', 'other_settlement_amount', 'other_amount']:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] != None else '-')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"

    def update(self, request, *args, **kwargs):
        user = self.request.iser
        instance = self.get_object()
        if instance.bill_state != 1:
            return Response({'error': '结算流水已绑定,不可重复操作'}, status=status.HTTP_400_BAD_REQUEST)
        record_array = self.request.data.get('record_array', None)
        if not record_array:
            return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            merchantsettlementrecord_set = MerchantSettlementRecord.objects.filter(is_bind=0, merchant_id=instance.merchant_id,
                                                           id__in=record_array,
                                                           settlement_time__gt=instance.receipts_time)
        except:
            return Response({'error': '无效清分记录参数'}, status=status.HTTP_400_BAD_REQUEST)
        if not merchantsettlementrecord_set:
            return Response({'error': '无效清分记录参数'}, status=status.HTTP_400_BAD_REQUEST)
        total_amount = merchantsettlementrecord_set.aggregate(Sum('amount'))['amount__sum']
        # if user.id != 1:
        if instance.bill_type == 2:
            if (instance.payable_amount + instance.other_settlement_amount) != total_amount:
                return Response({'error': '清分金额与结算金额不符'}, status=status.HTTP_400_BAD_REQUEST)
        else:
            if instance.payable_amount != total_amount:
                return Response({'error': '清分金额与结算金额不符'}, status=status.HTTP_400_BAD_REQUEST)
        for merchantsettlementrecord in merchantsettlementrecord_set:
            relations_data = {}
            relations_data['settlement_record_id'] = merchantsettlementrecord.id
            relations_data['bill_id'] = instance.id
            MerchantBillSettlementRecord.objects.get_or_create(defaults=relations_data,
                                                               settlement_record_id=merchantsettlementrecord.id,
                                                               bill_id=instance.id)
            merchantsettlementrecord.is_bind = 1
            merchantsettlementrecord.save()
        merchantsettlementrecord = merchantsettlementrecord_set[0]
        instance.account_name = merchantsettlementrecord.account_name
        instance.account_bank = merchantsettlementrecord.account_bank
        instance.account_number = merchantsettlementrecord.account_number
        instance.settlement_time = merchantsettlementrecord.settlement_time
        instance.settlement_record_id = merchantsettlementrecord.id
        instance.bill_state = merchantsettlementrecord.status
        instance.channel_id = merchantsettlementrecord.channel_id
        instance.settlement_amount = total_amount
        instance.save()
        return Response({'success': '操作成功'}, status=status.HTTP_200_OK)

    def synch_trading(self, request):
        # begin_time = self.request.data.get('begin_time', None)
        # end_time = self.request.data.get('end_time', None)
        # if not all([begin_time, end_time]):
        #     return Response({'error': '缺少必传参数'}, status=status.HTTP_400_BAD_REQUEST)
        # try:
        #     time_min1 = int(time.mktime(time.strptime(str(begin_time) + ' 00:00:00', "%Y-%m-%d %H:%M:%S")))
        #     time_max1 = int(time.mktime(time.strptime(str(end_time) + ' 00:00:00', "%Y-%m-%d %H:%M:%S")))
        # except:
        #     return Response({'error': '时间区间参数有误!'}, status=status.HTTP_400_BAD_REQUEST)
        # if time_max1 - time_min1 > 2678400:
        #     return Response({'error': '时区不得大于31天!'}, status=status.HTTP_400_BAD_REQUEST)
        # time_min1 = begin_time + ' 00:00:00'
        # time_max1 = end_time + ' 23:59:59'
        # sync_weiyoufu_trading({'begin_time': time_min1, 'end_time': time_max1})
        sync_weiyoufu_trading.delay()
        return Response({'success': '已提交后台处理,请稍后刷新看看'}, status=status.HTTP_200_OK)


class SpeedLoanUserInfoModelViewSet(ModelViewSet):

    def export_loanuserinfo(self, request):
        conn = pymysql.connect(host=settings.DATABASES['default']['HOST'],
                               port=settings.DATABASES['default']['PORT'],
                               database=settings.DATABASES['default']['NAME'],
                               user=settings.DATABASES['default']['USER'],
                               password=settings.DATABASES['default']['PASSWORD'])
        cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)
        sql = f'''
        SELECT c.*,d.prov_name,city_name,district_name,branch_name FROM (SELECT a.*,b.name FROM (SELECT * FROM tb_speed_loan_user_info WHERE id>4)AS a LEFT JOIN (SELECT id,name FROM tb_speed_loan_industry)AS b ON a.industry_id=b.id)AS c LEFT JOIN (SELECT id,prov_name,city_name,district_name,branch_name FROM tb_u_level)AS d ON c.level_id=d.id;
        '''
        cursor.execute(sql)
        ziduan = ['id', '客户手机号码', '客户姓名', '年龄', '经营行业', '所在地区(省)', '所在地区(市)', '所在地区(区)', '详细地址', '经营年限', '是否有固定房产', '微邮付商户号(参考)',
                  '所属市公司', '所属区县', '所属网点']
        cols = ['id', 'mobile', 'realname', 'age', 'name', 'province', 'city', 'district', 'address', 'business_limit', 'is_house', 'business_no', 'city_name',
                'district_name', 'branch_name']
        response = StreamingHttpResponse(self.get_loanuserinfo_fromat(cols, cursor, conn, ziduan))
        response['Content-Type'] = 'application/octet-stream; charset=gbk'
        response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path('极速贷商户信息.csv'))
        return response

    def get_loanuserinfo_fromat(self, cols, cursor, conn, ziduan):
        tmp_str = ""
        # 返回文件的每一列列名
        for col in ziduan:
            tmp_str += '"%s",' % (col)
        yield tmp_str.strip(",") + "\n"
        IS_HOUSE_ENUM = {
            0: '否',
            1: '是'
        }
        while True:
            tmp_str = ""
            row = cursor.fetchone()
            if row is None:
                cursor.close()
                conn.close()
                break
            for col in cols:
                if col == 'is_house':
                    tmp_str += '"%s",' % (IS_HOUSE_ENUM[row[col]])
                elif col in ['age']:
                    tmp_str += '"%s"岁,' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                elif col in ['business_limit']:
                    tmp_str += '"%s"年,' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
                else:
                    tmp_str += '"%s",' % (str(row[col]).encode('GBK', 'ignore').decode('gbk') if row[col] else '')
            yield tmp_str.strip(',') + "\n"


class GoodsModifyApplymentModelViewSet(ModelViewSet):

    def get_queryset(self):
        queryset = GoodsModifyApplyment.objects.all()
        return queryset

    # def get_serializer_class(self):


class ChannelModelViewSet(ModelViewSet):

    serializer_class = ChannelModelSerializer
    filter_backends = (filters.SearchFilter, DjangoFilterBackend)
    search_fields = ('name', )
    filter_class = ChannelFilter

    def get_queryset(self):
        queryset = Channel.objects.all()
        return queryset

    def hand_movement(self, request):
        try:
            id = self.request.query_params.get('id', '1')
            url_dict = {
                '1': 'http://47.107.132.8:8000/alilogin1/',
                '2': 'http://47.107.132.8:8000/post_alilogin/',
                '3': 'http://47.107.132.8:8000/jx_alilogin/'
            }
            id_dict = {
                '1': 1,
                '2': 14,
                '3': 8,
            }
            update_ali_cookie.delay({'url': url_dict[id], 'id': id_dict[id]})
        except:
            pass
        return Response({'success': '成功'}, status=status.HTTP_200_OK)

    def ruiyinxin(self, request):
        try:
            url = self.request.data.get('url', None)
            body = self.request.data.get('body', None)
            response = requests.post(url=url, data=eval(body))
            return Response(response.json(), status=status.HTTP_200_OK)
        except:
            return Response({'error': '出错了'}, status=status.HTTP_200_OK)




